在 Python 中,为什么回想起来列表理解中的 lambda 会覆盖自己?
In Python, why do lambdas in list comprehensions overwrite themselves in retrospect?
考虑以下代码:
def f (a):
return 1
def g (a):
return 2
[lambda a: i(a) for i in (f,g)][0](0)
结果是2,明明应该是1!我希望这段代码按如下方式执行。创建一个列表。将函数 f 复制到第一个索引中。将 g 复制到第二个索引中。 Fin.
为什么会这样执行?!
lambda 并没有覆盖自己,而是 i
被覆盖了。这是关于变量作用域的常见错误。试试这个:
[lambda a, i=i: i(a) for i in (f,g)][0](0)
(不同之处在于在创建 lambda 时绑定 i
的值)
另请参阅:
- Weird behavior: Lambda inside list comprehension
- What is “lambda binding” in Python?
- Python lambda's binding to local values
我会稍微扩展@dsh 的回答。
当列表理解表达式
[lambda a: i(a) for i in (f,g)]
被求值,它创建了两个匿名函数,每个函数的效果是
def _______(a):
return i(a)
但是,在对上述列表推导求值后,名称 i
绑定到其最后一次迭代值,即绑定到 g
的对象,即您的第 2 个函数。
现在,在那之后,当列表中的匿名函数之一被调用时,它访问模块全局范围内的名称 i
和 绑定到与 g
相同的东西是 .
编辑:哦,@dsh 也对其进行了扩展。
考虑以下代码:
def f (a):
return 1
def g (a):
return 2
[lambda a: i(a) for i in (f,g)][0](0)
结果是2,明明应该是1!我希望这段代码按如下方式执行。创建一个列表。将函数 f 复制到第一个索引中。将 g 复制到第二个索引中。 Fin.
为什么会这样执行?!
lambda 并没有覆盖自己,而是 i
被覆盖了。这是关于变量作用域的常见错误。试试这个:
[lambda a, i=i: i(a) for i in (f,g)][0](0)
(不同之处在于在创建 lambda 时绑定 i
的值)
另请参阅:
- Weird behavior: Lambda inside list comprehension
- What is “lambda binding” in Python?
- Python lambda's binding to local values
我会稍微扩展@dsh 的回答。
当列表理解表达式
[lambda a: i(a) for i in (f,g)]
被求值,它创建了两个匿名函数,每个函数的效果是
def _______(a):
return i(a)
但是,在对上述列表推导求值后,名称 i
绑定到其最后一次迭代值,即绑定到 g
的对象,即您的第 2 个函数。
现在,在那之后,当列表中的匿名函数之一被调用时,它访问模块全局范围内的名称 i
和 绑定到与 g
相同的东西是 .
编辑:哦,@dsh 也对其进行了扩展。