通过lambda定义的函数列表的意外行为



我想知道为什么下面两个打印会产生不同的结果:

f = [lambda x: x**2, lambda x: x+100]
f_new = [lambda x: fi(x) for fi in f]
print( [fi(2) for fi in f] )
print( [fi(2) for fi in f_new] )

输出为:

[4, 102]
[102, 102]

f_new中的两个lambda函数实际上调用的是同一个函数。

这是因为该列表是由捕获fi变量(在编译时)但并不实际执行该函数的lambdas组成的。因此,当列表通过生成器... for fi in f运行时,生成的lambda都使用捕获的变量fi,并以相同的函数指针(即f中的最后一个)结束

您需要在推导式中使用fi的当前值,以避免这种捕获副作用:

f_new = [(lambda fn:lambda x: fn(x))(fi) for fi in f]
print( [fi(2) for fi in f_new] )
[4, 102]

相关内容

  • 没有找到相关文章

最新更新