列表推导式和名称重新绑定
列表推导式是在 Python 中创建列表的简洁语法。然而,它们在与范围界定交互时表现出意想不到的行为。
考虑以下代码:
x = "original value" squares = [x**2 for x in range(5)] print(x) # Prints 4 in Python 2!
在此示例中,列表理解将变量 x 重新绑定到迭代中的当前值范围(5)。这种行为称为名称重新绑定。
名称重新绑定的原因
在 Python 2 中,列表推导式的实现方式与生成器表达式不同。通过将循环控制变量泄漏到周围范围来优化列表推导式的速度。另一方面,生成器表达式使用单独的执行框架,防止这种泄漏。
Python 3 的更改
在 Python 3 中,这种区别已被删除。列表推导式现在使用与生成器表达式相同的实现。因此,Python 3 中不再发生名称重新绑定。
后果
名称重新绑定可能会导致意外的行为和错误,特别是在变量名称相同的情况下用于列表理解和周围范围。正如问题中提到的,可以通过在列表推导式中使用下划线前缀作为临时变量来缓解此问题。
Python 的创建者 Guido van Rossum 解释了此更改背后的历史:在 Python 2 中,列表推导式泄露循环控制变量作为初始实现的工件以优化性能。然而,在 Python 3 中,这被认为是一个肮脏的小秘密,应该通过采用与生成器表达式相同的实现策略来修复。
以上是为什么 Python 2 的列表推导式会重新绑定变量,Python 3 是如何改变这一点的?的详细内容。更多信息请关注PHP中文网其他相关文章!