Python 列表理解重写值
看一下下面的代码片段,它显示了列表理解:
>>> i = 6
>>> s = [i * i for i in range(100)]
>>> print(i)
当您在 Python 2.6 中执行代码示例时,它会打印 99,但是当您在 Python 3.x 中执行它时,它会打印 6。
更改代码示例的原因是什么?行为以及为什么 Python 3.x 中的输出为 6?
Have a look at the following piece of code, which shows a list comprehension:
>>> i = 6
>>> s = [i * i for i in range(100)]
>>> print(i)
When you execute the code example in Python 2.6 it prints 99, but when you execute it in Python 3.x it prints 6.
What were the reasons for changing the behaviour and why is the output 6 in Python 3.x?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
旧的行为是一个错误,但由于某些代码依赖于它,因此无法轻易修复。
列表推导式中的变量
i
应该与顶层的变量i
不同。从逻辑上讲,它应该有自己的范围,不会扩展到理解之外,因为它的值只有在理解内部才有意义。但在 Python 2.x 中,由于实现细节,作用域大于必要的范围,导致变量“泄漏”到外部作用域,从而导致您看到令人困惑的结果。Python 3.0 故意不向后兼容以前的版本,因此他们利用这个机会修复了这种不良行为。
源
The old behaviour was a mistake but couldn't easily be fixed as some code relied on it.
The variable
i
inside the list comprehension should be a differenti
from the one at the top level. Logically it should have its own scope which does not extend outside the comprehension as its value only makes sense inside the comprehension. But in Python 2.x due to an implementation detail the scope was larger than necessary causing the variable to "leak" into the outer scope, causing the confusing results you see.Python 3.0 was deliberately not intended to be backwards compatible with previous releases, so they used the opportunity to fix this undesirable behaviour.
Source
是的,这是有原因的,原因是他们不希望列表理解中的临时变量泄漏到外部名称空间中。因此,这是一个有意的更改,是列表推导式现在成为将生成器表达式传递给 list() 的语法糖的结果。
参考:PEP3100。
Yes, there is a reason, and the reason is that they didn't want the temporary variable in a list comprehension to leak into the outer namespace. So it is an intentional change that is a result of list comprehensions now being syntactic sugar for passing a generator expression to list().
Ref: PEP3100.
马克·拜尔斯完美地回答了这个问题。
只是作为旁注..
在 Python 2.x 中,如果将括号更改为括号(创建生成器表达式而不是列表理解),您会注意到控制变量没有泄漏。
vs.
(当然,在Python 3中,这是固定的,列表推导式不再泄漏控制变量)
Mark Byers answered it perfectly.
just as a side note..
in Python 2.x, if you change your brackets to parens (creating a generator expression instead of a list comprehension), you will notice that the control variable is not leaked.
vs.
(of course, in Python 3, this is fixed and list comprehensions no longer leak control variables)
对我来说,范围似乎发生了变化。
我在Python 2.6中确认了你的结果;它确实打印了 99,这是列表理解中分配给 i 的最后一个值。
Looks like a change in scoping to me.
I confirmed your result in Python 2.6; it does indeed print 99, which is the last value assigned to i in the list comprehension.