[Tutor] "Strange" behaviour of list comprehension

Peter Otten __peter__ at web.de
Wed Feb 13 15:16:58 CET 2013


Mahadevan, Anand wrote:

> I'm playing around with list comprehension and in IDLE typed this in.  I
> actually wanted it to return all tuples satisfying the condition where z
> is the sum of x and y. I kind of got mixed up with the syntax, hence I put
> a comma in there instead of an "if".  I'd like some assistance
> understanding what it's doing... Thanks!
> 
>>>> somelist = [(x,y,z) for x in range(1,10) for y in range(x,10) for z in
>>>> range(y,10), x+y==z] somelist

If you're puzzled about a list comprehension, try translating it into for 
loops:

somelist = []
for x in range(1, 10):
    for y in range(x, 10):
        for z in range(y, 10), x+y==z:
            somelist.append((x, y, z))

In the first iteration you get x=1, y=1, so let's see what the inner loop 
gives:

>>> x = y = 1
>>> for z in range(y, 10), x+y==z:
...     print z
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined

So if you don't get a NameError you have defined z before entering the inner 
"loop". Let's fix that:

>>> z = 42
>>> for z in range(y, 10), x+y==z:
...     print z
... 
[1, 2, 3, 4, 5, 6, 7, 8, 9]
False

It should be obvious now that Python interprets

range(y, 10), x+y==z

as a tuple and iterates over that. range(1, 10) is a list in Python 2, so 
you are getting that first, then follows a boolean expression x+y == z which 
gives either True or False.



More information about the Tutor mailing list