第一种
f = [lambda x: x*i for i in range(4)] (如果将x换成i,调用时候就不用传参数,结果都为3)
对于上面的表达式,调用结果:
>>> f = [lambda x:x*i for i in range(4)]
>>> f[0](1)
3 # 1*3
>>> f[1](1)
3 # 1*3
>>> f[2](1)
3 # 1*3
>>> f[3](1)
3 # 1*3
>>> f[0](3)
9 # 3*3
>>> f[1](3)
9 # 3*3
>>> f[2](3)
9 # 3*3
>>> f[3](3)
9 # 3*3
上面的表达式展开如下:
def func():
fs = []
for i in range(4):
def lam(x):
return x*i
fs.append(lam)
return fs
当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。因为在每次循环中 lam函数都未绑定 i 的值,所以直到循环结束,i 的值为3,并将 lam 中所用到的 i 值定为 3 ,因此真正调用(例如f0)的时候 i 值保持不变(为3)。
展开后的调用方法:
>>> def func():
... fs = []
... for i in range(4):
... def lam(x):
... return x*i
... fs.append(lam)
... return fs
...
>>> f = func()
>>> f[0](3)
9
>>> f[2](3)
9
>>> f[1](3)
9
另一种将x换成i,就与传入的x值无关了。(这里 lambda 后面什么参数都不跟)
>>> f = [lambda :i*i for i in range(4)]
>>> f[0]()
9
>>> f[1]()
9
>>> f[2]()
9
>>> f[3]()
9
第二种
f1 = [lambda i=i: i*i for i in range(4)]
对于上面的表达式,调用结果:
>>> f1 = [lambda i=i: i*i for i in range(4)]
>>> f1[0]()
0
>>> f1[1]()
1
>>> f1[2]()
4
>>> f1[3]()
9
上面的表达式展开如下(为了更直观,替换了变量):
1 def func():
2 fs = []
3 for i in range(4)
4 def lam(x=i): # 即 i=i
5 return x*x # 即 i*i
6 fs.append(lam)
7 return fs
当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。但是在每次循环中 lam函数都将 i 值绑定到了 x 上,所以直到循环结束,不同地址的 lam 函数的 x 值为都不一样,因此真正调用(例如 f0)的时候 x 值都为当时被绑定的值。
但如果给 lam 函数传了参数,例如 f0,那么所有的调用结果都为传参的平方。与上面解释并不冲突,只是将传的参数绑定到了 x 上。
最后一种
f2 = [lambda x=i: i*i for i in range(4)]
哈哈哈哈,和第二种好像,只是变了一个字符,那么结果就大不一样了,哈哈哈哈
对于上面的表达式,调用结果:
>>> f2 = [lambda x=i: i*i for i in range(4)]
>>> f2[0]()
9
>>> f2[1]()
9
>>> f2[2]()
9
>>> f2[3]()
9
>>> f2[0](7)
9
>>> f2[1](7)
9
>>> f2[2](7)
9
传不传参数都不影响结果。展开后:
1 def func():
2 fs = []
3 for i in range(4)
4 def lam(x=i):
5 return i*i
6 fs.append(lam)
7 return fs
虽然 lam 函数将 i 的值绑定到了 x 上,但函数体中并未使用 x,所以直到循环结束,i 的值变为3,才会在调用时使用。其实同第一种情况是一样的。