我想知道为什么下面两个打印会产生不同的结果:
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]