Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenating two range function results

Does range function allows concatenation ? Like i want to make a range(30) & concatenate it with range(2000, 5002). So my concatenated range will be 0, 1, 2, ... 29, 2000, 2001, ... 5001

Code like this does not work on my latest python (ver: 3.3.0)

range(30) + range(2000, 5002) 
like image 547
MAG Avatar asked Dec 31 '12 09:12

MAG


People also ask

How do you combine two ranges in python?

Merge output of two range() functions Python doesn't have a built-in function to merge the result of two range() output. However, we can still be able to do it. There is a module named 'itertools' which has a chain() function to combine two range objects.

How do you join a range in a list in Python?

Use .join() method and pass the generator expression str(x) for x in range(...) to convert each integer to a string value first. This is necessary as the join function expects an iterable of strings and not integers.


2 Answers

You can use itertools.chain for this:

from itertools import chain concatenated = 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.

like image 106
Lev Levitsky Avatar answered Oct 03 '22 19:10

Lev Levitsky


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.

#!python3 import timeit number = 10000  t = 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 execution generator expression: 785.3081048010291 microsec/one execution 

... it is about 3 times faster.

like image 37
pepr Avatar answered Oct 03 '22 21:10

pepr