Connecting Tech Pros Worldwide Forums | Help | Site Map

nested list comprehension and if clauses

Jyotirmoy Bhattacharya
Guest
 
Posts: n/a
#1: Jun 28 '07
I'm a newcomer to Python. I have just discovered nested list
comprehensions and I need help to understand how the if-clause
interacts with the multiple for-clauses. I have this small program:

def multab(n):
print 'multab',n
return [n*i for i in range(5)]

print [(m,n) for m in range(5) for n in multab(m) if m>2]

It produces the output:
multab 0
multab 1
multab 2
multab 3
multab 4
[(3, 0), (3, 3), (3, 6), (3, 9), (3, 12), (4, 0), (4, 4), (4, 8), (4,
12), (4, 16)]

I was wondering if there is some way to write the if-clause so that it
is 'hoisted' out of the inner loop and the multab function is not
called at all for m=0,1,2. That would seem to be important if multab
were an expensive function.


Paul Rubin
Guest
 
Posts: n/a
#2: Jun 28 '07

re: nested list comprehension and if clauses


Jyotirmoy Bhattacharya <jmoy.matecon@gmail.comwrites:
Quote:
print [(m,n) for m in range(5) for n in multab(m) if m>2]
Quote:
I was wondering if there is some way to write the if-clause so that it
is 'hoisted' out of the inner loop and the multab function is not
called at all for m=0,1,2. That would seem to be important if multab
were an expensive function.
Maybe you mean

print [(m,n) for m in [a for a in range(5) if a 2] for n in multab(m)]

You'd probably really write

print [[(m,n) for m in range(3,5)] for n in multab(m)]

You should also use xrange instead of range, if the range might be
large. And you could use a generator expression instead of a listcomp
for the inner list.
Alex Martelli
Guest
 
Posts: n/a
#3: Jun 28 '07

re: nested list comprehension and if clauses


Jyotirmoy Bhattacharya <jmoy.matecon@gmail.comwrote:
Quote:
I'm a newcomer to Python. I have just discovered nested list
comprehensions and I need help to understand how the if-clause
interacts with the multiple for-clauses. I have this small program:
>
def multab(n):
print 'multab',n
return [n*i for i in range(5)]
>
print [(m,n) for m in range(5) for n in multab(m) if m>2]
>
It produces the output:
multab 0
multab 1
multab 2
multab 3
multab 4
[(3, 0), (3, 3), (3, 6), (3, 9), (3, 12), (4, 0), (4, 4), (4, 8), (4,
12), (4, 16)]
>
I was wondering if there is some way to write the if-clause so that it
is 'hoisted' out of the inner loop and the multab function is not
called at all for m=0,1,2. That would seem to be important if multab
were an expensive function.
Sure, just place the if clause where it needs to apply (between the two
for clauses) [apart from the fact that this example is best expressed by
using range(3,5), as somebody already said;-)].

Generally, the semantics of:

x = [<exprfor <F1if <I2for <F3>]

are exactly those of

x = []
for <F1:
if <I2:
for<F3:
x.append(expr)

and similarly for other mixes of for and if clauses (except that the
first clause must always be a for clause) -- you can always, simply and
mechanically conceptually translate them into an equivalent nest of for
and if statements, ending in a somelist.append(...) [where somelist may
be a "temporary anonymous" list if you're just going to use the listcomp
further rather than just assigning it to a name].


Alex
Paul Rubin
Guest
 
Posts: n/a
#4: Jun 28 '07

re: nested list comprehension and if clauses


aleax@mac.com (Alex Martelli) writes:
Quote:
Quote:
print [(m,n) for m in range(5) for n in multab(m) if m>2]
Sure, just place the if clause where it needs to apply (between the two
for clauses) [apart from the fact that this example is best expressed by
using range(3,5), as somebody already said;-)].
You mean

print [(m,n) for m in range(5) if m 2 for n in multab(m)]

Heh. I didn't realize you could do that. Thanks.
Alex Martelli
Guest
 
Posts: n/a
#5: Jun 28 '07

re: nested list comprehension and if clauses


Paul Rubin <http://phr.cx@NOSPAM.invalidwrote:
Quote:
aleax@mac.com (Alex Martelli) writes:
Quote:
Quote:
print [(m,n) for m in range(5) for n in multab(m) if m>2]
Sure, just place the if clause where it needs to apply (between the two
for clauses) [apart from the fact that this example is best expressed by
using range(3,5), as somebody already said;-)].
>
You mean
>
print [(m,n) for m in range(5) if m 2 for n in multab(m)]
>
Heh. I didn't realize you could do that. Thanks.
You're welcome (though a range(3,5) would still be better here:-).


Alex
Jyotirmoy Bhattacharya
Guest
 
Posts: n/a
#6: Jun 28 '07

re: nested list comprehension and if clauses


On Jun 28, 10:53 am, a...@mac.com (Alex Martelli) wrote:
Quote:
Jyotirmoy Bhattacharya <jmoy.mate...@gmail.comwrote:
Quote:
print [(m,n) for m in range(5) for n in multab(m) if m>2]
I was wondering if there is some way to write the if-clause so that it
is 'hoisted' out of the inner loop and the multab function is not
called at all for m=0,1,2. That would seem to be important if multab
were an expensive function.
Quote:
Generally, the semantics of:
>
x = [<exprfor <F1if <I2for <F3>]
>
are exactly those of
>
x = []
for <F1:
if <I2:
for<F3:
x.append(expr)
>
Thanks. That makes things completely clear to me.

Closed Thread


Similar Python bytes