List comprehension - NameError: name '_[1]' is not defined ?
Terry Reedy
tjreedy at udel.edu
Thu Jan 15 17:35:16 EST 2009
Peter Otten wrote:
> List comprehensions delete the helper variable after completion:
I do not believe they did in 2.4. Not sure of 2.5. There is certainly
a very different implementation in 3.0 and, I think, 2.6. OP
neglected to mention Python version he tested on. Code meant to run on
2.4 to 3.0 cannot depend on subtle listcomp details.
>>>> def f(): [i for i in [1]]
> ...
>>>> dis.dis(f)
> 1 0 BUILD_LIST 0
> 3 DUP_TOP
> 4 STORE_FAST 0 (_[1])
> 7 LOAD_CONST 1 (1)
> 10 BUILD_LIST 1
> 13 GET_ITER
> >> 14 FOR_ITER 13 (to 30)
> 17 STORE_FAST 1 (i)
> 20 LOAD_FAST 0 (_[1])
> 23 LOAD_FAST 1 (i)
> 26 LIST_APPEND
> 27 JUMP_ABSOLUTE 14
> >> 30 DELETE_FAST 0 (_[1])
> 33 POP_TOP
> 34 LOAD_CONST 0 (None)
> 37 RETURN_VALUE
>
In 3.0
>>> def f(): [i for i in [1]]
>>> import dis
>>> dis.dis(f)
1 0 LOAD_CONST 1 (<code object <listcomp> at
0x01349BF0, file "<pyshell#12>", line 1>)
3 MAKE_FUNCTION 0
6 LOAD_CONST 2 (1)
9 BUILD_LIST 1
12 GET_ITER
13 CALL_FUNCTION 1
16 POP_TOP
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
Running OP code in 3.0 with print ()s added gives
pre 0.a 1.b 2.c 3.d post
Traceback (most recent call last):
File "C:\Programs\Python30\misc\temp7.py", line 32, in <module>
""" % gie)
File "C:\Programs\Python30\misc\temp7.py", line 8, in __getitem__
return eval(expr, self.globals, self.locals)
File "<string>", line 7, in <module>
File "<string>", line 7, in <listcomp>
File "C:\Programs\Python30\misc\temp7.py", line 12, in ts
return ts % self
File "C:\Programs\Python30\misc\temp7.py", line 8, in __getitem__
return eval(expr, self.globals, self.locals)
File "<string>", line 2, in <module>
File "<string>", line 1, in <listcomp>
NameError: global name 'i' is not defined
> If you manage to run two nested listcomps in the same namespace you get a
> name clash and the inner helper variable overwrites/deletes the outer:
>
>>>> def xeval(x): return eval(x, ns)
> ...
>>>> ns = dict(xeval=xeval)
>>>> xeval("[xeval('[k for k in ()]') for i in (1,)]")
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 1, in xeval
> File "<string>", line 1, in <module>
> NameError: name '_[1]' is not defined
Which Python? 3.0 prints "[[]]"! But I think the nested listcomp *is*
in a separate namespace here. I will leave it to you or OP to disect
how his and your code essentially differ from 3.0 (and maybe 2.6)
implementation's viewpoint.
Terry Jan Reedy
More information about the Python-list
mailing list