Nested list comprehensions

Mike Meyer mwm at mired.org
Sun Nov 27 04:53:18 CET 2005

```neildunn at gmail.com writes:
> Hey guys:
>
>>>> [(i,j,k) for i in range(1,j) for j in range(1,k) for k in range(1,5)]
> [(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 1), (1, 2, 2), (1,
> 2, 3), (1, 2, 4), (1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (2, 1,
> 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 1), (2, 2, 2), (2, 2, 3),
> (2, 2, 4), (2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4)]

Give this a careful look: i varies slowest, and takes on the values 1
and 2. j varies next slowest, and takes on the values range(1, 4) in
both the i loops. k varies fastest, and goes through range(1, 5) in
all loops. I don't think it's doing what you intend.

>>>> def a():
> ...     print [(j,k) for j in range(1,k) for k in range(1,5)]
> ...
>>>> a()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 2, in a
> UnboundLocalError: local variable 'k' referenced before assignment
>
> Why is it that I can execute the nested list comprehension in the
> intepreter
> but if the same line is within a method declaration I get an unbound
> reference error?
>
> Is this a bug or am I missing some deep rule?

What are the values of the global variables j and k before you enter
the loop? Wouldn't happen to be 2 and 4, would they? Deleting them
first gives different results:

>>> del j
>>> del k
>>> [(i,j,k) for i in range(1,j) for j in range(1,k) for k in range(1,5)]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'j' is not defined

Methinks you want your for loops in the opposite order.

<mike
--
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/