Имеется список, состоящий из 0 и 1. Как найти длину самой длинной подпоследовательности стоящих подряд одинаковых элементов?
data = [0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]
max_length = 1
current_max_length = 1
for i in range(len(data)):
if i == data[i-1]:
current_max_length += 1
if i !=data[i-1]:
max_length == current_max_length
current_max_length = 1
if current_max_length > max_length:
max_length = current_max_length
Ответы (2 шт):
itertools.groupby
import itertools
data = [0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]
print(max(sum(1 for _ in g) for _, g in itertools.groupby(data)))
itertools.groupby(data) возвращает последовательность групп одинаковых элементов:
значение группа 0 [0] 1 [1, 1, 1] 0 [0] 1 [1] 0 [0, 0] 1 [1] 0 [0, 0, 0, 0, 0] 1 [1]
Значения нам не интересны - поэтому в коде есть _. У каждой группы g измеряется длина. Группа возвращается не целиком как список, а как итератор. sum(1 for _ in g) буквально считает сколько раз итератор сработает до исчерпания группы.
max выбирает максимальное значение.
Без библиотек
... задачу можно решить так:
data = [0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]
max_length = 0
length_ending_here = 0
prev = 0
for v in data:
if v == prev:
length_ending_here += 1
else:
length_ending_here = 1
if length_ending_here > max_length:
max_length = length_ending_here
prev = v
print(max_length)
Отличия от вашего кода:
переменные первоначально устанавливаются в ноль. Это нужно для правильной обработки пустого списка
data;предыдущее значение запоминается в
prev. Начальное значение может быть любое;цикл делается по значениям. Индексы не нужны, они только запутывают.
Отличий не так много.
Этот код можно ещё немного ускорить. Не буду этого делать - текущий код простой, а это важно чтобы убедится в его правильности.
Универсальный вариант. Подсчитывает для всех элементов списка: и для 0, и для 1 и т.д. Позволяет выполнять другие расчеты, не только max.
from itertools import groupby
from collections import defaultdict
# в конец списка добавил несколько "инородных" элементов исключительно для демонстрации возможностей
data = [0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 'a', 'a', 'a']
keys_lst = list() #список сгруппированных элементов
len_lst = list() #список количеств повторяющихся элементов
keys_lst = [str(k) for k, _ in groupby(data)] #для единообразия все ключи строковые
len_lst = [len(list(g)) for _, g in groupby(data)] #вычисляем размер группы
dict_full = defaultdict(list) #словарь, в который соберем вместе элементы и их количество повторов по группам
for k, v in zip(keys_lst, len_lst):
dict_full[k].append(v)
#Выводим для примера варианты подсчетов. Тут можно еще пофантазировать
for k in dict_full.keys():
print(f'Min for {k}: {min(dict_full[k])}')
print(f'Max for {k}: {max(dict_full[k])}')
print(f'Total for {k}: {sum(dict_full[k])}')
print(f'Counter for {k}: {len(dict_full[k])}')
Для удобства облачим в функцию:
from itertools import groupby
from collections import defaultdict
from typing import Union
def Counting_List(
data_list: list, #список с данными
key_name: str = None, #элемент, для которого нужно выполнить подсчет
result_name: str = "Total", #какой именно нужен подсчет
) -> Union[int, float, None]: #на всякий случай добавлен float
keys_lst = list()
len_lst = list()
dict_full = defaultdict(list)
#словарь, в котором задаем функции для подсчета различных значений
# если элемент (ключ key_name) не найден, вернет 0
dict_results = dict()
dict_results = {
"total": lambda: sum(dict_full.get(key_name, [0])),
"min": lambda: min(dict_full.get(key_name, [0])),
"max": lambda: max(dict_full.get(key_name, [0])),
}
keys_lst = [str(k) for k, _ in groupby(data_list)]
len_lst = [len(list(g)) for _, g in groupby(data_list)]
for k, v in zip(keys_lst, len_lst):
dict_full[k].append(v)
# переводим в нижний регистр для исключения ошибок написания
# если метод подсчета не удалось распознать, то возвращаем None (можно заменить на 0)
return dict_results.get(result_name.lower(), lambda: None)()
Оба варианта позволяют выполнять разновариантные подсчеты для практически любых элементов списка не зависимо от их количества. В качестве побочного эффекта можно подсчитать количество символов в строке, хотя для этого удобнее использовать другие методы.