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?
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.
Range objects don't have an append or extend methods, so we have to convert the object to a list before using the methods.
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).
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 range
s in Python 3 or lists
s in Python 2.
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
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With