Вы можете использовать list comprehension с generator expression и сочетание enumerate() и itertools.groupby():
>>> import itertools
>>> l = [0, 1, 2, 3, 4, 7, 8, 9, 11]
>>> [[t[0][1], t[-1][1]] for t in
... (tuple(g[1]) for g in itertools.groupby(enumerate(l), lambda (i, x): i - x))]
[[0, 4], [7, 9], [11, 11]]
Во-первых, enumerate()
будет строить кортежи из элементов списка и их соответствующий индекс:
>>> [t for t in enumerate(l)]
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 7), (6, 8), (7, 9), (8, 11)]
Тогда groupby()
сгруппирует те кортежи, использующие разницу между их индекса и их значение (которое будет одинаковым для последовательных значений):
>>> [tuple(g[1]) for g in itertools.groupby(enumerate(l), lambda (i, x): i - x)]
[((0, 0), (1, 1), (2, 2), (3, 3), (4, 4)), ((5, 7), (6, 8), (7, 9)), ((8, 11),)]
Оттуда, нам нужно только создавать списки из значений первых и последних кортежей каждой группы (которая будет таким же, если группа содержит только один элемент).
Вы также можете использовать [(t[0][1], t[-1][1]) ...]
, чтобы создать список кортежей диапазона вместо вложенных списков, или даже ((t[0][1], t[-1][1]) ...)
превратить все выражение в Iterable generator
, который лениво строить кортежи диапазона на лету.
Почти такой же вопрос был задан и ответ в http://stackoverflow.com/questions/3429510/pythonic-way-to-convert-a-list-of-integers-into-a-string-of -comma-separate-range/3430231 # 3430231 – Apalala
'>>> import this' – Apalala
Ну, я могу с уверенностью сказать, что я не знаю такой функции. Гораздо сложнее сказать с уверенностью, что чего-то, чего я не знаю, не существует .... –