Terry Reedy wrote: > 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.
As Mario said, 2.4, 2.5, and 2.6 all show the same behaviour. > 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. 3.0 behaves different. Like generator expressions listcomps no longer leak the loop variable, and this is implemented by having each listcomp execute as a nested function: > 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 This is more robust (at least I can't think of a way to break it like the 2.x approach) but probably slower due to the function call overhead. The helper variable is still there, but the possibility of a clash with another helper is gone (disclaimer: I didn't check this in the Python source) so instead of # 2.5 and 2.6 (2.4 has the names in a different order) >>> def f(): ... [[i for i in ()] for k in ()] ... >>> f.func_code.co_varnames ('_[1]', 'k', '_[2]', 'i') we get # 3.0 >>> def f(): ... [[i for i in ()] for k in ()] ... >>> f.__code__.co_varnames () The variables are gone from f's scope, as 3.x listcomps no longer leak their loop variables. >>> f.__code__.co_consts (None, <code object <listcomp> at 0x2b8d7f6d7530, file "<stdin>", line 2>, ()) >>> outer = f.__code__.co_consts[1] >>> outer.co_varnames ('.0', '_[1]', 'k') Again the inner listcomp is separated from the outer. >>> outer.co_consts (<code object <listcomp> at 0x2b8d7f6d26b0, file "<stdin>", line 2>, ()) >>> inner = outer.co_consts[0] >>> inner.co_varnames ('.0', '_[1]', 'i') Peter -- http://mail.python.org/mailman/listinfo/python-list