Se puede utilizar un list comprehension con un generator expression y una combinación de enumerate() y 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]]
En primer lugar, enumerate()
construirá tuplas de los elementos de la lista y su respectivo índice:
>>> [t for t in enumerate(l)]
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 7), (6, 8), (7, 9), (8, 11)]
Entonces groupby()
agrupará esas tuplas utilizando la diferencia entre su índice y su valor (que será igual para los valores consecutivos):
>>> [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),)]
a partir de ahí, sólo tenemos que crear listas de los valores de la primera y última tuplas de cada grupo (que será el mismo si el grupo sólo contiene un artículo).
También puede utilizar [(t[0][1], t[-1][1]) ...]
para construir una lista de tuplas rango en lugar de las listas anidadas, o incluso ((t[0][1], t[-1][1]) ...)
para convertir toda la expresión en un iterable generator
que perezosamente va a construir las tuplas alcance sobre la marcha.
Casi la misma pregunta fue formulada y respondida en http://stackoverflow.com/questions/3429510/pythonic-way-to-convert-a-list-of-integers-into-a-string-of -comma-separated-range/3430231 # 3430231 – Apalala
'>>> importar esto' – Apalala
Bueno, puedo decir con confianza que no conozco esa función. Es mucho más difícil decir con confianza que algo de lo que no estoy al tanto no existe ... –