multiple discontinued ranges

X

xoff

I was wondering what the best method was in Python programming for 2
discontinued ranges. e.g. I want to use the range 3 to 7 and 17 to 23.
Am I obliged to use 2 for loops defining the 2 ranges like this:

for i in range (3,7):
do bla
for i in range (7,17):
do bla

or is there a more clever way to do this?
 
P

Paul Rudin

xoff said:
I was wondering what the best method was in Python programming for 2
discontinued ranges. e.g. I want to use the range 3 to 7 and 17 to 23.
Am I obliged to use 2 for loops defining the 2 ranges like this:

for i in range (3,7):
do bla
for i in range (7,17):
do bla

or is there a more clever way to do this?


for i in itertools.chain(xrange(3,7), xrange(17,23)):
print i
 
P

Paul Rubin

xoff said:
I was wondering what the best method was in Python programming for 2
discontinued ranges. e.g. I want to use the range 3 to 7 and 17 to 23.

you could use itertools.chain:

from itertools import chain

for i in chain(range(3,7), range(17,23)):
...

I'm assuming you're using python 3. In python 2 each of those ranges
expands immediately to a list, so on the one hand they're consuming
potentially lots of storage (you should use xrange instead). On the
other hand you could just concatenate the lists with +, but I wouldn't
advise that.
 
X

xoff

you could use itertools.chain:

  from itertools import chain

  for i in chain(range(3,7), range(17,23)):
    ...

I'm assuming you're using python 3.  In python 2 each of those ranges
expands immediately to a list, so on the one hand they're consuming
potentially lots of storage (you should use xrange instead).  On the
other hand you could just concatenate the lists with +, but I wouldn't
advise that.

I am curious, why wouldn't you advise something like this:
for i in chain(range(3,7) + range(17,23)):

Thanks again!
 
M

Mel

xoff said:
I was wondering what the best method was in Python programming for 2
discontinued ranges. e.g. I want to use the range 3 to 7 and 17 to 23.
Am I obliged to use 2 for loops defining the 2 ranges like this:

for i in range (3,7):
do bla
for i in range (7,17):
do bla

or is there a more clever way to do this?

One horribly clever way is to concoct a 9-th order polynomial to return
3,4,5,6,17,18,19,20,21,22 for input values 0,1,2,3,4,5,6,7,8,9.

The reasonable way is to use two loops as you've done. If the pattern of
discontinuous ranges is really important in your application, you'd perhaps
want to package it up (not tested):

def important_range ():
for x in xrange (3, 7):
yield x
for x in xrange (17,23):
yield x


to be used elsewhere as

for v in important_range():
# use v ...



Mel.
 
P

Peter Otten

xoff said:
I was wondering what the best method was in Python programming for 2
discontinued ranges. e.g. I want to use the range 3 to 7 and 17 to 23.
Am I obliged to use 2 for loops defining the 2 ranges like this:

for i in range (3,7):
do bla
for i in range (7,17):
do bla

or is there a more clever way to do this?
.... for i in r:
.... print i,
....
3 4 5 6 17 18 19 20 21 22
 
N

Nobody

I am curious, why wouldn't you advise something like this:
for i in chain(range(3,7) + range(17,23)):

Because it constructs all three lists (both of the individual ranges and
their concatenation) in memory. For a trivial example, that isn't a
problem; for a real application, it could be.
 
E

Emile van Sebille

potentially lots of storage (you should use xrange instead). On the
other hand you could just concatenate the lists with +, but I wouldn't
advise that.

I am curious, why wouldn't you advise something like this:
for i in chain(range(3,7) + range(17,23)):[/QUOTE]


I'd assume because concatenation is generally considered expensive.

If you were to do it, you'd likely drop the chain and write:

for i in range(3,7) + range(17,23):

Emile
 
M

MRAB

I am curious, why wouldn't you advise something like this:
for i in chain(range(3,7) + range(17,23)):
In Python 3 'range' is a generator, like 'xrange' in Python 2.
 
P

Paul Rubin

xoff said:
I am curious, why wouldn't you advise something like this:
for i in chain(range(3,7) + range(17,23)):

First of all, the outer chain does nothing. Second, concatenating the
two lists creates a new list, consuming storage and taking time copying
all the elements. Third, if there are n lists instead of two, I think
the copying time is O(n**2) in the number of lists because there are n-1
separate copy operations and they keep getting larger.
 
C

cbrown

One horribly clever way is to concoct a 9-th order polynomial to return
3,4,5,6,17,18,19,20,21,22 for input values 0,1,2,3,4,5,6,7,8,9.

And one would want one with integer coefficients... truly horribly
clever! A good example of complex is better than complicated...
The reasonable way is to use two loops as you've done. If the pattern of
discontinuous ranges is really important in your application, you'd perhaps
want to package it up (not tested):

def important_range ():
for x in xrange (3, 7):
yield x
for x in xrange (17,23):
yield x

Reasonable; but DRY: don't repeat yourself. IMNSHO, better would be:

.... def important_range ():
.... for x in [xrange (3, 7), xrange (17,23)]:
.... for y in x:
.... yield y

because face it, you're probably going to add to that list of ranges
anyway, so you should anticipate it (and there's no cost if you don't
end up adding to it).

To extend that notion, I would imagine that itertools.chain is already
basically defined as:

.... def chain(*args):
.... for x in args:
.... for y in x:
.... yield y

so important_range() can then be simply defined as:

.... def important_range:
.... return chain(xrange (3, 7), xrange (17,23))

Cheers - Chas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top