[Python-Dev] Seeming unintended difference between list comprehensions and generator expressions...

Josiah Carlson josiah.carlson at gmail.com
Fri Feb 20 23:40:16 CET 2009


Recently I found the need to generate some constants inside a class
body.  What I discovered was a bit unintuitive, and may not be
intended...

In 2.5 and 2.6:
>>> class foo:
...     x = {}
...     x.update((i, x.get(i, None)) for i in xrange(10))
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
  File "<stdin>", line 3, in <genexpr>
NameError: global name 'x' is not defined
>>> class foo:
...     x = {}
...     x.update([(i, x.get(i, None)) for i in xrange(10)])
...
>>>

In 3.0:
>>> class foo():
...     x = {}
...     x.update((i, x.get(i, None)) for i in range(10))
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
  File "<stdin>", line 3, in <genexpr>
NameError: global name 'x' is not defined
>>> class foo():
...     x = {}
...     x.update([(i, x.get(i, None)) for i in range(10)])
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
  File "<stdin>", line 3, in <listcomp>
NameError: global name 'x' is not defined
>>>


The behavior of 3.0 WRT list comprehensions behaving the same way as
generator expressions is expected, but why generator expressions
(generally) don't keep a reference to the class scope during execution
seems to be unintended.

 - Josiah


More information about the Python-Dev mailing list