[Python-ideas] Temporary variables in comprehensions

Terry Reedy tjreedy at udel.edu
Thu Feb 15 21:31:33 EST 2018


On 2/15/2018 8:37 PM, Chris Barker - NOAA Federal wrote:

> Back to one of your examples:
> 
> [f(x) for x in [x]]
> 
> What does that mean???
> 
> for x in seq
> 
> Means iterate through seq, and assign each item to the name x.
> 
> If that seq has x in it — I’m not sure that is even legal python — the 
> scope in a comprehension confuses me.
> 
> But that is the equivalent is something like:
> 
> it= iter(seq)
> while True:
>      Try:
>          x = next(it)
>      Except StopIteration:
>          Break
> 
> (Excuse the caps — hard to write code on a phone)
> 
> So not sure how x gets into that sequence before the loop starts.

Reusing a previously bound name as an iteration variable is a bad idea. 
It works in 3.x because the outermost iterable, but only the outermost 
iterable, is pre-calculated before executing the comprehension.  Hence 
'x in [x]' sometimes works, and sometimes not.  ('Outermost' is topmost 
in nested loops, left most in comprehension.)

 >>> x = 2
 >>> [x*x for x in [x]]
[4]
 >>> [x*y for x in [3] for y in [x]]  # here, local x is 3, not 2
[9]
 >>> [x*y for y in [x] for x in [3]]
[6]
 >>> [x*y for y in [3] for x in [x]]
Traceback (most recent call last):
   File "<pyshell#4>", line 1, in <module>
     [x*y for y in [3] for x in [x]]
   File "<pyshell#4>", line 1, in <listcomp>
     [x*y for y in [3] for x in [x]]
UnboundLocalError: local variable 'x' referenced before assignment
 >>> [z*y for y in [3] for z in [x]]  # no confusion here
[6]

To put it another way, l = [x for x in [x]] is actually calculated as
_temp = [x]; l = [x for x in _temp].  In general, other iterables cannot 
be precalculated since they might depend on prior iteration variables.


-- 
Terry Jan Reedy




More information about the Python-ideas mailing list