Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I combine range() functions

For some code I'm writing, I need to iterate from 1-30 skipping 6. What I tried naively is

a = range(1,6)
b = range(7,31)

for i in a+b:
    print i

Is there a way to do it more efficiently?

like image 504
boson Avatar asked Aug 19 '13 15:08

boson


People also ask

How do you combine ranges in python?

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.

Can you append a range?

Range objects don't have an append or extend methods, so we have to convert the object to a list before using the methods.

How do you exclude a range in Python?

If you want to exclude 0 then change your range to (1,11). The way range works is the lower limit is inclusive where as upper limit is exclusive. On an unrelated note, if your lower limit is 0, you need not include the lower limit and write it as range(11) which is same as range(0,11).


2 Answers

Use itertools.chain:

import itertools

a = range(1,6)
b = range(7,31)

for i in itertools.chain(a, b):
    print i

Or tricky flattening generator expressions:

a = range(1,6)
b = range(7,31)
for i in (x for y in (a, b) for x in y):
    print i

Or skipping in a generator expression:

skips = set((6,))
for i in (x for x in range(1, 31) if x not in skips):
    print i

Any of these will work for any iterable(s), not just ranges in Python 3 or listss in Python 2.

like image 81
agf Avatar answered Sep 30 '22 04:09

agf


In python 2 you are not combining "range functions"; these are just lists. Your example works just well. But range always creates a full list in memory, so a better way if only needed in for loop could be to to use a generator expression and xrange:

range_with_holes = (j for j in xrange(1, 31) if j != 6)

for i in range_with_holes:
    ....

In generator expression the if part can contain a complex logic on which numbers to skip.

Another way to combine iterables is to use the itertools.chain:

range_with_holes = itertools.chain(xrange(1, 6), xrange(7, 31))

Or just skip the unwanted index

for i in range(1, 31):
    if i == 6:
        continue

    ...