Вы можете использовать список с генератором выражения и комбинацией 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]) ...)
, чтобы превратить все выражение в итерируемое generator
, который будет лениво создавать кортежи диапазона на лету.