评估一系列Python lambda函数只会评估最后一个元素

14 投票
3 回答
6893 浏览
提问于 2025-04-16 17:57

我有一系列的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.

我觉得只有最后一个函数被执行了,其他的都没有。有没有什么想法?谢谢!

3 个回答

1
lst.append(lambda x: f(x,i))

我不是Python专家,但是不是有可能Python把i当作一个引用来处理呢?然后,在循环结束后,i就等于它最后被赋的值(4),当调用函数时,它们跟着i的引用,找到4,然后用这个值来执行。

声明:这可能是胡说八道。

2

试试使用 partial,这对我有效:

from functools import partial

def f(x,z):
    print "x=",x,", z=",z

lst = [ partial(f,z=i) for i in range(5) ]

for fn in lst:
    fn(3)

http://docs.python.org/library/functools.html#functools.partial

20

这个 lambda 表达式只是查找全局变量 'i' 的值。

你可以试试下面这个:

for i in range(0,5):
  lst.append(lambda x, z=i: f(x,z))

撰写回答