Как я могу найти непрерывные последовательности повторяющихся элементов в списке? - PullRequest
0 голосов
/ 13 мая 2019

Мне нужно написать функцию, которая дает список целых чисел L и целое число n, он возвращает True, если список содержит последовательную последовательность из единиц длины n и False в остальном.

Допустим, мой список: L = [1,2,3,4,1,1,1,2,3,4] и n = 3. Функция должна возвращать True, потому что на 5-й позиции их 3.

Я пытался с:

def consecutive (L,n):
    for i in range(len(L)):
        if [1]*n in L:
            return True
    return False
L = [1,2,3,4,1,1,1,2,3,4]
n = 3
consecutive (L,n)

Но это, конечно, не работает, потому что [1]*3 генерирует [1,1,1], а внутри L.

нет подсписков.

Есть ли способ использовать списки? Что-то вроде:

L = [1,2,3,4,1,1,1,2,3,4]
result = all(x==(1,1,1) for x in range(0,len(L)+1,3))
result

Опять же, я знаю, что это не работает, потому что каждый элемент x не может быть равен (1,1,1). Я записал это, чтобы дать представление о том, что у меня на уме.

Ответы [ 5 ]

1 голос
/ 13 мая 2019

Одним из способов является использование itertools.groupby, что позволяет группировать последовательные значения в списке. Следующее понимание генератора возвращает True, если найдено заданное key из 1, а длина его соответствующих значений >=, чем n.

Мы можем использовать next, чтобы прекратить итерации, как только будет возвращен первый True:

from itertools import groupby
n = 3

next((True for k,v in groupby(L) if k == 1 and len(list(v)) >= n), False)
# True
0 голосов
/ 13 мая 2019

Как сказал @yatu, использование itertools, очевидно, лучший способ сделать это.

Но это можно воспроизвести, сжав фрагменты исходного списка. Например, чтобы сгруппировать элементы списка по 3, вы можете сделать:

l = [1, 2, 3, 4, 1, 1, 1, 2, 3, 4]

def groupby3(a_list):
    return zip(a_list[:-2], a_list[1:-1], a_list[2:])

print([l for l in groupby3(l)])
# [(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 1), (1, 1, 1), (1, 1, 2), (1, 2, 3), (2, 3, 4)]

Группировать элементы по любому номеру немного сложнее, так как мы должны динамически строить срез:

l = [1, 2, 3, 4, 1, 1, 1, 2, 3, 4]

def groupbyn(a_list, n):
    # computes the bounds of slices to use
    bounds = ((start or None, start - n + 1 or None) for start in range(n))
    # builds a slice for each generated bounds couple
    slices = (slice(start, stop) for start, stop in bounds)
    # apply the generated slices
    sliced = (a_list[slice] for slice in slices)
    # return the sipped slices
    return zip(*sliced)

print([l for l in groupbyn(l, 3)])
# [(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 1), (1, 1, 1), (1, 1, 2), (1, 2, 3), (2, 3, 4)]
print([l for l in groupbyn(l, 2)])
# [(1, 2), (2, 3), (3, 4), (4, 1), (1, 1), (1, 1), (1, 2), (2, 3), (3, 4)]
print([l for l in groupbyn(l, 5)])
# [(1, 2, 3, 4, 1), (2, 3, 4, 1, 1), (3, 4, 1, 1, 1), (4, 1, 1, 1, 2), (1, 1, 1, 2, 3), (1, 1, 2, 3, 4)]

Тогда вы можете использовать эту функцию groupbyn для решения вашей проблемы:

n = 3
print((1, ) * n in groupbyn(l, n))  # True
n = 4
print((1, ) * n in groupbyn(l, n))  # False
0 голосов
/ 13 мая 2019

Следующее будет работать, если вы хотите знать, повторяется ли любой элемент списка. Следующее возвращает True тогда и только тогда, когда есть последовательность n копий любого элемента:

def consecutive (L,n):
    if len(L) < 1:
        return False
    if n <= 1:
        return True

    # at this point n >= 2
    elem = L[0]
    count = 1
    # so far, we have seen one copy of `elem`

    for i in range(1, len(L)):
        if L[i] == elem:
            count = count + 1
            if count >= n:
                return True
        else: # L[i] != elem
            elem = L[i]
            count = 1
    return False

Если есть элемент , определенный , который вы хотите повторить, подумайте о следующем:

def consecutive (L,n, elem):
    count = 0
    for i in range(len(L)):
        if L[i] == elem:
            count = count + 1
            if count >= n:
                return True
        else: # L[i] != elem
            count = 0
    return False
0 голосов
/ 13 мая 2019

Если вы не хотите импортировать модули (я полагаю, это домашняя работа), вы можете сделать что-то вроде этого:

n = 3
L = [1,2,3,4,1,1,1,2,3,4]
find = [1] * n

locations = [index for index in range(len(L)) if index <= len(L) and L[index: index + len(find)] == find]

for location in locations:
    print(f"Found {find} at index {location}.")

Выход:

Found [1, 1, 1] at index 4.

Хотя вы, возможно, захотите сделать это далеко, вместо того, чтобы понимать список для изучения языка.

0 голосов
/ 13 мая 2019

Без использования импорта

Пример:

L = [1,2,3,4,1,1,1,2,3,4]
n = 3
def consecutive (L,n):
    c = 0
    for i in L:
        if i == 1:
            c += 1
        else:
            c = 0
        if c >= n:
            return True
    return False


print(consecutive(L,n))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...