Eric Eric - 1 year ago 111
Python Question

NameError in nested comprehensions

I have this code in a file

class Sudoku(dict):
COLUMNS = [
{(x, y) for y in xrange(9)} for x in xrange(9)
]


When I run
python broken.py
, I get the traceback:

Traceback (most recent call last):
File "U:\broken.py", line 1, in <module>
class Sudoku(dict):
File "U:\broken.py", line 3, in Sudoku
{(x, y) for y in xrange(9)} for x in xrange(9)
File "U:\broken.py", line 3, in <setcomp>
{(x, y) for y in xrange(9)} for x in xrange(9)
NameError: global name 'x' is not defined
[Finished in 0.1s with exit code 1]


I don't really see the problem here. Isn't
x
defined in the comprehension?




What's stranger is how this seems to execute without an error when pasted directly into the python interpreter...




EDIT: This works if I use a list comprehension rather than a set comprehension

Answer Source

I've filed a bug here. This is still broken by design in python 2.7.5.

From the bug report:

In Python 2, list comprehensions don't have their own scope, so the x in your initial example lives at class scope. However, the set comprehension does have its own scope. By design, a variable defined at class scope is not visible to inner scopes inside that class.

In Python 3, this works because the list comprehension has its own scope.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download