Combining a list of ranges in python

Question:

What is the easiest way to construct a list of consecutive integers in given ranges, like this?

[1,2,3,4,5,6,7,  15,16,17,18,19,  56,57,58,59]

I know the start and end values of each group.
I tried this:

ranges = (  range(1,8),
            range(15,20),
            range(56,60)  )
Y = sum( [ list(x) for x in  ranges ] )

which works, but seems like a mouthful. And in terms of code legibility, the sum() is just confusing. In MATLAB it’s just

Y = [ 1:7, 15:19, 56:59 ]

Is there an better way? Can use numpy if easier.

Bonus question

Can anybody explain why it doesn’t work if I use a generator for the sum?

Y = sum( (list(x) for x in ranges) )

TypeError: unsupported operand types for +: ‘int’ and ‘list’

Seems like it doesn’t know the starting value should be [] rather than 0!

Asked By: Sanjay Manohar

||

Answers:

One option, and maybe the closest to the Matlab syntax, is to use the star operator:

>>> [*range(1,8), *range(15,20), *range(56, 60)]
[1, 2, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 56, 57, 58, 59]
Answered By: fsimonjetz

You could write your own generator helper function:

def ranges(*argses):
    for args in argses:
        yield from range(*args)


for x in ranges((1, 7), (15, 19), (56, 59)):
    print(x)

If you need an actual list out of those multi-ranges, then list(ranges(...)).

Answered By: AKX

The matlab syntax has it’s equivalent in with numpy.r_:

import numpy as np

np.r_[1:7, 15:19, 56:59]

output: array([ 1, 2, 3, 4, 5, 6, 15, 16, 17, 18, 56, 57, 58])

For a list:

np.r_[1:7, 15:19, 56:59].tolist()

output: [1, 2, 3, 4, 5, 6, 15, 16, 17, 18, 56, 57, 58]

Answered By: mozway

You could you use itertool’s chain.from_iterable, which lazily evaluates the args from a single interable:

>>> list(itertools.chain.from_iterable((range(1,8), range(15,20), range(56,60))))
[1, 2, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 56, 57, 58, 59]
Answered By: user3468054

To fix your code with sum, you can specify an empty list as the start keyword argument as the starting point of aggregation:

sum((list(x) for x in ranges), start=[])
Answered By: blhsing
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.