即使在理解范围之后,列表理解也会重新绑定名称。这是正确的吗?

2023-12-02

推导式显示出与范围界定的不寻常交互。这是预期的行为吗?

x = "original value"
squares = [x**2 for x in range(5)]
print(x)  # Prints 4 in Python 2!

冒着抱怨的风险,这是一个残酷的错误来源。当我编写新代码时,我偶尔会发现由于重新绑定而导致的非常奇怪的错误 - 即使现在我知道这是一个问题。我需要制定一条规则,例如“始终在列表推导式中使用下划线作为临时变量的前缀”,但即使这样也不是万无一失的。 事实上,这种随机定时炸弹等待的事实否定了列表理解的所有良好的“易用性”。


列表推导式在 Python 2 中会泄漏循环控制变量,但在 Python 3 中不会泄漏。这是 Guido van Rossum(Python 的创建者)解释这背后的历史:

我们还对 Python 进行了另一项更改 3、提高列表之间的等价性 理解式和生成器 表达式。在 Python 2 中,列表 理解“泄漏”循环控制 变量进入周围范围:

x = 'before'
a = [x for x in 1, 2, 3]
print x # this prints '3', not 'before'

这是原作的神器 列表理解的实现; 它是 Python 的“肮脏的小东西”之一 多年来的“秘密”。一开始是 有意妥协以列入名单 理解速度快得令人眼花缭乱,并且 虽然这不是一个常见的陷阱 初学者,绝对会刺痛人 偶尔。发电机用 表达式我们不能这样做。 生成器表达式已实现 使用生成器,其执行 需要一个单独的执行框架。 因此,生成器表达式 (特别是如果他们迭代 短序列)效率较低 比列表推导式。

然而,在 Python 3 中,我们决定 修复列表的“肮脏的小秘密” 使用相同的理解 实施策略为 生成器表达式。因此,在Python中 3、上面的例子(之后 修改为使用 print(x) :-) 将 打印“之前”,证明“x” 暂时在列表理解中 阴影但不覆盖“x” 周围范围内。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

即使在理解范围之后,列表理解也会重新绑定名称。这是正确的吗? 的相关文章

随机推荐