grouping a flat list of number by range

Steven Bethard steven.bethard at gmail.com
Fri Jun 2 13:01:43 EDT 2006


joh12005 at yahoo.fr wrote:
> i'm looking for a way to have a list of number grouped by consecutive
> interval, after a search, for example :
> 
> [3, 6, 7, 8, 12, 13, 15]
> 
> =>
> 
> [[3, 4], [6,9], [12, 14], [15, 16]]

Know your itertools.  From the examples section[1]:

"""
# 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(operator.itemgetter(1), g)
...
[1]
[4, 5, 6]
[10]
[15, 16, 17, 18]
[22]
[25, 26, 27, 28]
"""


So I think something like this should work:

 >>> import itertools
 >>> def intervals(numbers):
...     def key((i, n)):
...         return i - n
...     for key, group in itertools.groupby(enumerate(numbers), key):
...         group = list(group)
...         _, first_n = group[0]
...         _, last_n = group[-1]
...         yield first_n, last_n + 1
...
 >>> list(intervals([3, 6, 7, 8, 12, 13, 15]))
[(3, 4), (6, 9), (12, 14), (15, 16)]

If you really need lists instead of tuples, just put brackets around the 
terms in the yield statement.

[1] http://docs.python.org/lib/itertools-example.html

STeVe



More information about the Python-list mailing list