[Tutor] list comprehensions isolate variables but for loops don't - is there a special usage?

Peter Otten __peter__ at web.de
Wed Jun 5 10:05:49 CEST 2013


Alan Gauld wrote:

> On 05/06/13 06:53, Jim Mooney wrote:
>> I just noticed that a list comprehension doesn't change a same-name
>> variable outside of it, but a for loop does.
>>
>> For some reason it bothers me that a for loop can do this. Is there a
>> simple usage that isolates the for loop iteration variable the way a
>> list comprehension does?
> 
> No, and it's unlikely to change since a lot of code relies on the fact
> that the for loop iteration variable remembers the last value in the
> loop. This is especially so in loops that have a break exit since its
> useful to know how far through the sequence it got to.
> 
> To be honest I didn't realize that comprehensions (and I assume
> generators in general) created their own local namespace. But thinking
> about it, it seems logical since they are effectively functions in
> disguise... Whereas for loops are structures of the language just like
> if statements or while loops. They live in whichever context they are
> used.

Caveat: The behaviour was unified in Python 3. List comprehensions in 2.x 
did leak the loop variable...

>>> def f():
...     [x for x in "abc"]
...     print x
... 
>>> f()
c

while generator expressions did not leak:

>>> def g():
...     list(x for x in "abc")
...     print x
... 
>>> g()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in g
NameError: global name 'x' is not defined


Until 2.6 you could even access the underlying iterator under a name like 
"_[1]", but that has been cleaned up in 2.7 it seems.



More information about the Tutor mailing list