lambda表示式 Python 之 for迴圈中的lambda
阿新 • • 發佈:2019-01-11
Python 之 for迴圈中的lambda
第一種
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
上面的表示式展開如下:
1 def func():
2 fs = []
3 for i in range(4): 4 def lam(x): 5 return x*i 6 fs.append(lam) 7 return fs
當呼叫 func() 時,每迴圈一次,將 lam 函式的地址存到 fs 中。因為在每次迴圈中 lam函式都未繫結 i 的值,所以直到迴圈結束,i 的值為3,並將 lam 中所用到的 i 值定為 3 ,因此真正呼叫(例如f[0](3))的時候 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 值為都不一樣,因此真正呼叫(例如 f[0]())的時候 x 值都為當時被繫結的值。
但如果給 lam 函式傳了引數,例如 f[0](8),那麼所有的呼叫結果都為傳參的平方。與上面解釋並不衝突,只是將傳的引數繫結到了 x 上。
>>> f1 = [lambda i=i: i*i for i in range(4)]
>>> f1[0](8)
64
>>> f1[1](8) 64 >>> f1[2](8) 64 >>> f1[3](8) 64
最後一種
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,才會在呼叫時使用。其實同第一種情況是一樣的