On Wed, Feb 13, 2013 at 2:45 PM, Mahadevan, Anand <maha...@labcorp.com>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
> [(1, 1, [1, 2, 3, 4, 5, 6, 7, 8, 9]), (1, 1, False), (1, 2, [2, 3, 4, 5,
> 6, 7, 8, 9]), (1, 2, False), (1, 3, [3, 4, 5, 6, 7, 8, 9]), (1, 3, False),
> (1, 4, [4, 5, 6, 7, 8, 9]), (1, 4, False), (1, 5, [5, 6, 7, 8, 9]), (1, 5,
> False), (1, 6, [6, 7, 8, 9]), (1, 6, False), (1, 7, [7, 8, 9]), (1, 7,
> False), (1, 8, [8, 9]), (1, 8, False), (1, 9, [9]), (1, 9, False), (2, 2,
> [2, 3, 4, 5, 6, 7, 8, 9]), (2, 2, False), (2, 3, [3, 4, 5, 6, 7, 8, 9]),
> (2, 3, False), (2, 4, [4, 5, 6, 7, 8, 9]), (2, 4, False), (2, 5, [5, 6, 7,
> 8, 9]), (2, 5, False), (2, 6, [6, 7, 8, 9]), (2, 6, False), (2, 7, [7, 8,
> 9]), (2, 7, False), (2, 8, [8, 9]), (2, 8, False), (2, 9, [9]), (2, 9,
> False), (3, 3, [3, 4, 5, 6, 7, 8, 9]), (3, 3, False), (3, 4, [4, 5, 6, 7,
> 8, 9]), (3, 4, False), (3, 5, [5, 6, 7, 8, 9]), (3, 5, False), (3, 6, [6,
> 7, 8, 9]), (3, 6, False), (3, 7, [7, 8, 9]), (3, 7, False), (3, 8, [8, 9]),
> (3, 8, False), (3, 9, [9]), (3, 9, False), (4, 4, [4, 5, 6, 7, 8, 9]), (4,
> 4, False), (4, 5, [5, 6, 7, 8, 9]), (4
>  , 5, False), (4, 6, [6, 7, 8, 9]), (4, 6, False), (4, 7, [7, 8, 9]), (4,
> 7, False), (4, 8, [8, 9]), (4, 8, False), (4, 9, [9]), (4, 9, False), (5,
> 5, [5, 6, 7, 8, 9]), (5, 5, False), (5, 6, [6, 7, 8, 9]), (5, 6, False),
> (5, 7, [7, 8, 9]), (5, 7, False), (5, 8, [8, 9]), (5, 8, False), (5, 9,
> [9]), (5, 9, False), (6, 6, [6, 7, 8, 9]), (6, 6, False), (6, 7, [7, 8,
> 9]), (6, 7, False), (6, 8, [8, 9]), (6, 8, False), (6, 9, [9]), (6, 9,
> False), (7, 7, [7, 8, 9]), (7, 7, False), (7, 8, [8, 9]), (7, 8, False),
> (7, 9, [9]), (7, 9, False), (8, 8, [8, 9]), (8, 8, False), (8, 9, [9]), (8,
> 9, False), (9, 9, [9]), (9, 9, False)]
>

This list comprehension is basically interpreted like so:

 [(x,y,z) for x in range(1,10) for y in range(x,10) for z in (range(y,10),
x+y==z)]

To be more precise, the comma at the end is part of a tuple (you can omit
parentheses of a tuple in many cases). This makes the final for loop
iterate over the tuple (range(y, 10), x + y == z). You'll notice that this
only works if the variable 'z' is already defined, since the tuple isn't
constructed in the for loop. In other words, if we just run the code in a
clean interpreter we'll get a NameError:

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
on win32
Type "copyright", "credits" or "license()" for more information.
>>> [(x,y,z) for x in range(1,10) for y in range(x,10) for z in
range(y,10), x+y==z]

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    [(x,y,z) for x in range(1,10) for y in range(x,10) for z in
range(y,10), x+y==z]
NameError: name 'z' is not defined

What happened in your case is probably you were running different
variations of the list comprehension in the same interpreter session. Since
the iterating variable in a for loop still exists after the for loop exits,
we won't encounter this error if we run a slightly different list
comprehension first:

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]
on win32
Type "copyright", "credits" or "license()" for more information.
>>> [(x,y,z) for x in range(1,10) for y in range(x,10) for z in range(y,10)
if x+y==z]
[(1, 1, 2), (1, 2, 3), (1, 3, 4), (1, 4, 5), (1, 5, 6), (1, 6, 7), (1, 7,
8), (1, 8, 9), (2, 2, 4), (2, 3, 5), (2, 4, 6), (2, 5, 7), (2, 6, 8), (2,
7, 9), (3, 3, 6), (3, 4, 7), (3, 5, 8), (3, 6, 9), (4, 4, 8), (4, 5, 9)]
>>> z
9
>>>

As you can see, z exists after we run a for loop with z in it. Its value is
still at the value it had during the last iteration. The same applies to x
and y. Looking at your output, you had values of x, y and z in your
interpreter session such that x + y == z evaluated to False. So the third
value in your tuples is cycling between range(y, 10) and False.

HTH,
Hugo
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to