问题
用lambda定义了一个匿名函数,想在定义时捕获到某些变量的值。
解决方案
先看下面代码的效果:
x = 10
a = lambda y: y + x
x = 20
b = lambda y: y + x
猜想一下:a(10)
和 b(10)
返回的结果是什么?如果你认为结果是20
和 30
,那么就错了:
print(a(10))
30
print(b(10))
30
lambda
表达式中的x是一个自由变量, 是在运行时绑定值,而不是定义时就绑定,即lambda表达式中的x是执行时的值,这与函数的默认值参数定义是不同的。例如:
x = 15
print(a(10))
25
x = 3
print(a(10))
13
如果想让匿名函数,在定义时就捕获到参数值,可以将那个参数值定义成默认参数即可,例如:
m = 10
c = lambda n, m = m: m + n
print(c(10))
20
m = 2
print(c(10))
20
讨论
有时候,可能会不恰当的使用lambda
表达式。 比如,通过在一个循环或列表推导中创建一个lambda
表达式列表,并期望函数能在定义时就记住每次的迭代值。例如:
funcs = [lambda x: x+n for n in range(3)]
for f in funcs:
print(f(0))
2
2
2
但是实际效果是,n的值为迭代的最后一个值。将参数值设置为默认参数,才能得到想要的效果,修改代码如下:
funcs = [lambda x, n = n: x+n for n in range(3)]
for f in funcs:
print(f(0))
0
1
2
网友评论