Welcome, guest | Sign In | My Account | Store | Cart

This code makes ranges of contiguous numbers from a list of integers. Each range is 2-integers-tuple which is same as for builtin range() function's argument.

Python, 34 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def list2range(lst):
    '''make iterator of ranges of contiguous numbers from a list of integers'''

    tmplst = lst[:]
    tmplst.sort()
    start = tmplst[0]

    currentrange = [start, start + 1]

    for item in tmplst[1:]:
        if currentrange[1] == item:
            # contiguous
            currentrange[1] += 1
        else:
            # new range start
            yield tuple(currentrange)
            currentrange = [item, item + 1]

    # last range
    yield tuple(currentrange)



if __name__ == '__main__':
    # test routine
    a = [1,2,3,4,5,6,7,8,10,11,12,23,24,25,26]
    b = [(1,9), (10,13), (23, 27)]
    c = list(list2range(a))

    if b != c:
        print 'failed!'
    else:
        print 'succeed!'
    print c

3 comments

Poor Yorick 15 years, 6 months ago  # | flag

only works if list doesn't contain duplicate values. try weeding out duplicate values first:

tmplst = list(set(tmplst)) tmplst.sort() start = tmplst[0] ...

Raymond Hettinger 15 years, 6 months ago  # | flag

Contrast with the example in the itertools docs. See http://www.python.org/doc/current/lib/itertools-example.html

>>> 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]
Kazuo Moriwaka (author) 15 years, 6 months ago  # | flag

duplicate values. Thank you for your comment! I forgot duplicate values.

Created by Kazuo Moriwaka on Sun, 7 May 2006 (PSF)
Python recipes (4591)
Kazuo Moriwaka's recipes (2)

Required Modules

  • (none specified)

Other Information and Tasks