Python: определить длину последовательности равных элементов в списке - PullRequest
7 голосов
/ 19 октября 2010

У меня есть следующий список:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]

Я хочу определить длину последовательности равных элементов, т. Е. Для данного списка я хочу, чтобы вывод был:

[(0, 6), (1, 6), (0, 4), (2, 3)]

(или аналогичный формат).

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

Сейчас мое решение выглядит так:

out = []
cnt = 0

last_x = l[0]  
for x in l:
    if x == last_x:
        cnt += 1
    else:
        out.append((last_x, cnt))
        cnt = 1
    last_x = x
out.append((last_x, cnt))

print out

Мне интересно, есть ли более питонский способ сделать это.

Ответы [ 2 ]

14 голосов
/ 19 октября 2010

Вы почти наверняка захотите использовать itertools.groupby :

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
answer = []
for key, iter in itertools.groupby(l):
    answer.append((key, len(list(iter))))

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)]

Если вы хотите повысить эффективность использования памяти, но при этом добавить больше сложности, вы можете добавить функцию длины:

def length(l):
    if hasattr(l, '__len__'):
        return len(l)
    else:
        i = 0
        for _ in l:
            i += 1
        return i

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
answer = []
for key, iter in itertools.groupby(l):
    answer.append((key, length(iter)))

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)]

Обратите внимание, что я не тестировал функцию length (), и вполне возможно, что она замедлит вас.

3 голосов
/ 19 октября 2010

Хороший ответ Майка, но itertools._grouper, возвращаемый groupby, никогда не будет иметь метода __len__, поэтому нет смысла проверять его

Я использую sum(1 for _ in i) для получения длины itertools._группа

>>> import itertools as it
>>> L = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
>>> [(k, sum(1 for _ in i)) for k, i in it.groupby(L)]
[(0, 6), (1, 6), (0, 4), (2, 3)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...