[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