gpt4 book ai didi

python - Lambda 函数在 Python 3 和 Python 2 中的行为不同

转载 作者:太空狗 更新时间:2023-10-29 22:11:18 27 4
gpt4 key购买 nike

为什么要写这段代码

>>> i=1
>>> add_one=lambda x:x+i
>>> my_list=[add_one(i) for i in [0,1,2]]

在 Python 2.7 中抛出这个结果:

>>> my_list
[0, 2, 4]

但是 Python 3.3 中的相同代码会抛出另一个结果:

>>> my_list
[1, 2, 3]

Python 2.7 的结果对我来说更有意义,因为“i”变量与调用 lambda 函数的名称范围相同。我不理解 Python 的两个分支中 lambda 函数的这些不平等行为。

最佳答案

不同之处在于,在 Python 3 中,列表推导式不会将其变量泄漏到封闭范围内。你可以看到 Guido 对此的一些讨论 here ;该帖子包含一个与您的示例非常相似的示例。

在这两个版本中,您的add_one(i) 都是一个引用变量i 的函数。调用函数时,将在封闭范围内按名称查找此变量。由于该函数是在全局模块级别定义的,因此“封闭范围”是全局范围。这意味着当您调用 add_one 时,它将使用它在全局范围内找到的 i 的任何值(即,它将查找名为 i< 的全局变量)。

在 Python 2 中,列表理解将其变量 i 泄漏到封闭范围。由于您的列表理解是在全局模块级范围内,因此“封闭范围”再次是全局的,并且泄漏的变量 i 是一个全局变量,覆盖了您最初用 设置的值i = 1 行。调用 add_one 然后引用这个变量。由于 i 随每次迭代而变化,因此您的函数在每次迭代时有效地执行 i+i

在 Python 3 中,列表理解在私有(private)范围内创建自己的变量。但是您的函数仍然访问全局 i。由于 Python 3 列表理解不会泄漏到全局范围,这个全局 i 永远不会改变,并且你的函数在每次迭代时有效地执行 x+1 (其中 x 是列表理解的循环变量)。

关于python - Lambda 函数在 Python 3 和 Python 2 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22288604/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com