nested list comprehension and if clauses

Alex Martelli aleax at mac.com
Thu Jun 28 07:53:26 CEST 2007


Jyotirmoy Bhattacharya <jmoy.matecon at gmail.com> wrote:

> 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 = [<expr> for <F1> if <I2> for <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



More information about the Python-list mailing list