[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