Python, разделяющий список на основе недостающих чисел в последовательности

Я ищу большую часть pythonic способа разделить список чисел в меньшие списки на основе числа, отсутствующего в последовательности. Например, если первоначальный список был:

seq1 = [1, 2, 3, 4, 6, 7, 8, 9, 10]

функция уступила бы:

[[1, 2, 3, 4], [6, 7, 8, 9, 10]]

или

seq2 = [1, 2, 4, 5, 6, 8, 9, 10]

привел бы к:

[[1, 2], [4, 5, 6], [8, 9, 10]]
19
задан JoshAdel 9 July 2011 в 20:57
поделиться

2 ответа

Из документации Python :

>>> # Find runs of consecutive numbers using groupby.  The key to the solution
>>> # is differencing with a range so that consecutive numbers all appear in
>>> # same group.
>>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
...     print map(itemgetter(1), g)
...
[1]
[4, 5, 6]
[10]
[15, 16, 17, 18]
[22]
[25, 26, 27, 28]

Функция groupby () из модуля itertools генерирует прерывание каждый раз, когда ключевая функция меняет свое возвращаемое значение. Уловка заключается в том, что возвращаемое значение - это число в списке за вычетом позиции элемента в списке. Эта разница меняется, когда есть пробелы в числах.

Функция itemgetter () взята из модуля оператора , вам нужно будет импортировать ее и модуль itertools, чтобы этот пример работал.

Полный пример с вашими данными:

>>> from operator import itemgetter
>>> from itertools import *
>>> seq2 = [1, 2, 4, 5, 6, 8, 9, 10]
>>> list = []
>>> for k, g in groupby(enumerate(seq2), lambda (i,x):i-x):
...     list.append(map(itemgetter(1), g))
... 
>>> print list
[[1, 2], [4, 5, 6], [8, 9, 10]]

Или как понимание списка:

>>> [map(itemgetter(1), g) for k, g in groupby(enumerate(seq2), lambda (i,x):i-x)]
[[1, 2], [4, 5, 6], [8, 9, 10]]
40
ответ дан 30 November 2019 в 02:36
поделиться

Другой вариант, не требующий itertools и т.д.:

>>> data = [1, 4, 5, 6, 10, 15, 16, 17, 18, 22, 25, 26, 27, 28]
>>> spl = [0]+[i for i in range(1,len(data)) if data[i]-data[i-1]>1]+[None]
>>> [data[b:e] for (b, e) in [(spl[i-1],spl[i]) for i in range(1,len(spl))]]
... [[1], [4, 5, 6], [10], [15, 16, 17, 18], [22], [25, 26, 27, 28]]
5
ответ дан 30 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: