评估Python lambda函数列表时,只评估最后一个列表元素。

14

我有一个lambda函数列表,我想按顺序对它们进行求值。但是我不确定为什么,只有最后一个函数会被求值。下面是一个例子:

  >>> def f(x,z):
  ...     print "x=",x,", z=",z
  ... 
  >>> 
  >>> g = lambda x : f(x,13)
  >>> g(2)
  x= 2 , z= 13    # As expected
  >>> 
  >>> lst=[]
  >>> 
  >>> for i in range(0,5): 
  ...    lst.append(lambda x: f(x,i))
  ... 
  >>> print lst
  [<function <lambda> at 0x10341e2a8>, <function <lambda> at 0x10341e398>, <function <lambda> at 0x10341e410>, <function <lambda> at 0x10341e488>, <function <lambda> at 0x10341e500>]
  >>> 
  >>> for fn in lst:
  ...   fn(3)
  ... 
  x= 3 , z= 4 # z should be 0
  x= 3 , z= 4 # z should be 1
  x= 3 , z= 4 # z should be 2
  x= 3 , z= 4 # z should be 3
  x= 3 , z= 4 # as expected.

我认为只有最后一个被执行了,其他的没有。有什么想法吗?谢谢!


谢谢!我有一种模糊的感觉,它是指全局空间中的变量,但我不知道该搜索什么。非常感谢!! - Nawal
出于好奇,这个有什么使用场景? - Katriel
3个回答

20
lambda函数只是在查找全局变量'i'的值。
请尝试以下方法:
for i in range(0,5):
  lst.append(lambda x, z=i: f(x,z))

2

我从未使用过这个,而下面bluepnume的帖子看起来更容易使用。干杯! - Nawal
实际上这是一个相当不错的解决方案。在这种情况下使用部分视图非常有意义。 - bluepnume
谢谢 ;) 我个人也更喜欢列表推导式而不是 for/append 方式。 - Yannick Loiseau

1
不是Python专家,但Python是否将i视为
lst.append(lambda x: f(x,i))

作为一个参考?然后,在循环之后,i等于其最后分配的值(4),当函数被调用时,它们遵循它们的i引用,找到4,并使用该值执行。

声明:可能是无意义的。


是的!(来自Jon Skeet上面给出的链接)。谢谢! - Nawal
你很接近了。当调用 lambda 函数时,它会查找 i,而在全局作用域中,i 等于 4,因为这是循环中设置的最后一个值。 - bluepnume

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接