Найдите количество последовательных элементов, которые будут одинаковыми до их изменения
Так, например, если у меня есть списки
a = [1,1,1,2,2] b = [1,1,2,2,2] c = [2,1,1,1,1]
Я бы хотел получить самую длинную полосу первого элемента в списке, так что, например, a
дал бы 3, b
дал бы 2 и c
дал бы 1. Я знаю, что могу создать цикл while и посчитать последовательность таким образом, но Мне было интересно, есть ли более элегантный способ сделать это?
- Как найти среднее значение для каждой подобной записи в списке кортежей?
- Python: list.index не находит существующий элемент
- вывод вложенного списка со списком
- Печатать элементы списка с пониманием (python)
- Учет списков в Python: установите все элементы в массиве в 0 или 1
вы можете сделать что-то вроде этого:
numStreak = ([a[0] == n for n in a]+[False]).index(False)
(это также гарантирует, что если все элементы похожи на первый элемент, индекс возвращает правильное значение)
UPDATE: более эффективная (но менее элегантная?) Версия
from itertools import takewhile len([1 for _ in takewhile(lambda x:x==a[0], a)])
или немного лучше (ОБНОВЛЕНИЕ 2) предложение @ vaultah:
sum(1 for _ in takewhile(lambda x:x==a[0], a))
Вы можете использовать groupby и суммировать количество элементов в первой группе для каждого:
a = [1,1,1,2,2] b = [1,1,2,2,2] c = [2,1,1,1,1] from itertools import groupby for l in [a,b,c]: print(sum( 1 for _ in next(groupby(l), [[], []],)[1]))
Или используя takewhile:
from itertools import takewhile for l in [a, b, c]: print(sum((1 for _ in takewhile(lambda x: x == l[0], l))))
Если ваши данные всегда являются списком, кортежем и т. Д. В группе, вы можете проверить значение ложности, а не устанавливать значение по умолчанию в next(..
:
for l in [a, b, c]: print(sum(1 for _ in next(groupby(l))[1]) if l else 0)
Один лайнер для дороги? Прицел …
a = [5,5,5,5,8] list(np.ediff1d(a)).count(0)+1 >>> 4
-a = [5,5,5,5,8] list(np.ediff1d(a)).count(0)+1 >>> 4
Вы можете использовать numpy:
>>> import numpy as np >>> a = [1,1,1,2,2] >>> b = [1,1,2,2,2] >>> c = [2,1,1,1,1] >>> def runs(data): ... return np.split(data, np.where(np.diff(data) != 0)[0]+1) ... >>> for e in a,b,c: ... runs(np.array(e)) ... [array([1, 1, 1]), array([2, 2])] [array([1, 1]), array([2, 2, 2])] [array([2]), array([1, 1, 1, 1])]
Затем просто возьмите длину первого запуска:
>>> for e in a,b,c: ... len(runs(np.array(e))[0]) ... 3 2 1
Или, в Python, просто используйте цикл while:
>>> def r(a): ... i=1 ... while a[0]==a[i]: i+=1 ... return i ... >>> r(a) 3 >>> r(b) 2 >>> r(c) 1
- Как удалить элемент из списка Python по значению?
- Почему remove () не удаляет последний экземпляр дубликатов в списке Python
- Python zip ключом
- сравнить два списка и вернуть не соответствующие элементы
- Изменить начальный индекс списка в python?
- Python обрезает нестандартный сегмент в строке
- Транспонирование вложенного списка в python
- Копирование содержимого файла в многомерный список в Python
- Почему кортежи занимают меньше места в памяти, чем списки?