Поиск последовательно повторяющихся строк в списке Python

Каков наиболее эффективный способ поиска последовательно повторяющихся строк в списке Python?

Например, предположим, что у меня есть список ["a", "a", "b", "c", "b","b","b"]. Я хочу получить что-то вроде: ["group of 2 a found at index 0, group of 3 b found at index 4'].

Есть ли встроенная функция для выполнения этой задачи? Я нашел numpy.bincount, но, похоже, работает только с числовыми значениями.

Заранее спасибо за помощь.

2 ответа

Смешно, что вы должны назвать его группой, потому что функция, которая, вероятно, лучше всего подходит для этого, это itertools.groupby:

>>> import itertools
>>> items = ["a", "a", "b", "c", "b", "b", "b"]
>>> [(k, sum(1 for _ in vs)) for k, vs in itertools.groupby(items)]
[('a', 2), ('b', 1), ('c', 1), ('b', 3)]

(sum(1 for _ in vs) - это счет, кстати, поскольку len не работает только с любым итерабельным, а len(list(…)) расточительно.)

Получение индекса немного сложнее; Id просто делайте это с помощью цикла.

import itertools

def group_with_index(l):
 i = 0

 for k, vs in itertools.groupby(l):
 c = sum(1 for _ in vs)
 yield (k, c, i)
 i += c


Это требует информации о состоянии между элементами цикла, поэтому его непросто сделать со списком. Вместо этого вы можете отслеживать последнее значение в цикле:

groups = []
for i, val in enumerate(["a", "a", "b", "c", "b","b","b"]):
 if i == 0:
 cnt = 1
 loc = i
 last_val = val
 elif val == last_val:
 cnt += 1
 else:
 groups.append((cnt, last_val, loc))
 cnt = 1
 loc = i
 last_val = val

for group in groups:
 print("group of {0} {1} found at index {2}".format(*group)

Вывод:

group of 2 a found at index 0
group of 1 b found at index 2
group of 1 c found at index 3

licensed under cc by-sa 3.0 with attribution.