Concatenating two range function results Concatenating two range function results python-3.x python-3.x

Concatenating two range function results


You can use itertools.chain for this:

from itertools import chainconcatenated = chain(range(30), range(2000, 5002))for i in concatenated:     ...

It works for arbitrary iterables. Note that there's a difference in behavior of range() between Python 2 and 3 that you should know about: in Python 2 range returns a list, and in Python3 an iterator, which is memory-efficient, but not always desirable.

Lists can be concatenated with +, iterators cannot.


I like the most simple solutions that are possible (including efficiency). It is not always clear whether the solution is such. Anyway, the range() in Python 3 is a generator. You can wrap it to any construct that does iteration. The list() is capable of construction of a list value from any iterable. The + operator for lists does concatenation. I am using smaller values in the example:

>>> list(range(5))[0, 1, 2, 3, 4]>>> list(range(10, 20))[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]>>> list(range(5)) + list(range(10,20))[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

This is what range(5) + range(10, 20) exactly did in Python 2.5 -- because range() returned a list.

In Python 3, it is only useful if you really want to construct the list. Otherwise, I recommend the Lev Levitsky's solution with itertools.chain. The documentation also shows the very straightforward implementation:

def chain(*iterables):    # chain('ABC', 'DEF') --> A B C D E F    for it in iterables:        for element in it:            yield element

The solution by Inbar Rose is fine and functionally equivalent. Anyway, my +1 goes to Lev Levitsky and to his argument about using the standard libraries. From The Zen of Python...

In the face of ambiguity, refuse the temptation to guess.

#!python3import timeitnumber = 10000t = timeit.timeit('''\for i in itertools.chain(range(30), range(2000, 5002)):    pass''','import itertools', number=number)print('itertools:', t/number * 1000000, 'microsec/one execution')t = timeit.timeit('''\for x in (i for j in (range(30), range(2000, 5002)) for i in j):    pass''', number=number)print('generator expression:', t/number * 1000000, 'microsec/one execution')

In my opinion, the itertools.chain is more readable. But what really is important...

itertools: 264.4522138986938 microsec/one executiongenerator expression: 785.3081048010291 microsec/one execution

... it is about 3 times faster.


Can be done using list-comprehension.

>>> [i for j in (range(10), range(15, 20)) for i in j][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19]

Works for your request, but it is a long answer so I will not post it here.

note: can be made into a generator for increased performance:

for x in (i for j in (range(30), range(2000, 5002)) for i in j):    # code

or even into a generator variable.

gen = (i for j in (range(30), range(2000, 5002)) for i in j)for x in gen:    # code