嵌套推导中的NameError

时间:2012-09-04 08:08:56

标签: python list-comprehension

我在文件中有这段代码

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

当我运行python broken.py时,我得到追溯:

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]

我真的没有在这里看到问题。理解中是否定义了x


直接粘贴到python解释器中时,如果没有错误,这似乎是如何执行的...


编辑:如果我使用列表理解而不是集合理解,则此方法有效

5 个答案:

答案 0 :(得分:8)

我提交了一个错误here。在python 2.7.5中,这是仍然被打破的

来自错误报告:

  

在Python 2中,列表推导没有自己的范围,因此初始示例中的x位于类范围内。但是,集合理解确实有自己的范围。按照设计,在类范围内定义的变量对该类内部范围不可见。

     

在Python 3中,这是有效的,因为列表推导有自己的范围。

答案 1 :(得分:3)

狂野的猜测,但是使用Python 2.7和3.0引入了Python集合理解:您是否会使用旧版本来执行您的脚本,而最近使用的是您的解释器?


在查看Python文档的this section之后,我看不到这种行为的解释。此外,它与列表理解一起工作的事实清楚地表明它不是范围问题。

我只看到两个可能的原因:

  • 集合理解实施中的错误
  • 使用不支持集合理解的前Python版本。

答案 2 :(得分:2)

我担心我不知道为什么你的代码不起作用,但是,以下工作并给你你想要的东西:

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

也许这个网站上的一些python大师可以启发我们为什么你的代码片段失败。

答案 3 :(得分:1)

我希望我能给出一个理论上的解释,但这有效:

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

if __name__ == "__main__":
    s = Sudoku()
    print s.COLUMNS

答案 4 :(得分:1)

也许这就是你真正想要的东西:

[[{x:y} for x in xrange(9)] for y in xrange(9)]