Python列表理解覆盖值

Jos*_*hua 18 python closures list-comprehension

看看下面这段代码,它显示了一个列表理解.

>>> i = 6
>>> s = [i * i for i in range(100)]
>>> print(i)
Run Code Online (Sandbox Code Playgroud)

当您在Python 2.6中执行代码示例时,它会打印99,但是当您在Python 3.x中执行它时,它会打印6.

是什么改变行为的原因,以及为什么是输出6的Python 3.x的

先感谢您!

Mar*_*ers 32

旧的行为是一个错误,但不能轻易修复,因为一些代码依赖它.

i列表推导中的变量应该i与顶层的变量不同.从逻辑上讲,它应该有自己的范围,它不会超出理解范围,因为它的价值只在理解中有意义.但是在Python 2.x中由于实现细节,范围大于必要导致变量"泄漏"到外部范围,导致您看到的混乱结果.

故意不打算将Python 3.0与以前的版本向后兼容,因此他们利用这个机会修复了这种不良行为.

在Python 2.3及更高版本中,列表推导将其包含的每个控件变量"泄漏"到包含的范围中.但是,这种行为已被弃用,依赖它不会在Python 3.0中起作用

资源


Len*_*bro 7

是的,有一个原因,原因是他们不希望列表解析中的临时变量泄漏到外部命名空间.所以这是一个有意的改变,它是列表推导的结果,现在是将生成器表达式传递给list()的语法糖.

参考:PEP3100.


Cor*_*erg 5

马克·拜尔斯回答得很完美。

只是作为一个注释。.
在Python 2.x中,如果将方括号更改为括号(创建生成器表达式而不是列表推导),则会注意到控件变量没有泄漏。

>>> i = 6
>>> s = (i for i in range(100))
>>> print i
6
Run Code Online (Sandbox Code Playgroud)

>>> i = 6
>>> s = [i for i in range(100)]
>>> print i
99
Run Code Online (Sandbox Code Playgroud)

(当然,在Python 3中,这是固定的,列表理解不再是泄漏控制变量)