2015-03-25 65 views
7

我一直在努力讓lambda工作。這裏的代碼是示例,但它很好地顯示了我的問題。爲什麼我的lambda不起作用?

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 


print lambdas[0](1) 
print lambdas[2](1) 

這給我16,但我希望對不同lambda有不同的值。爲什麼會發生!

+0

「Python中的範圍是詞法,閉包永遠記住變量的名稱和範圍,而不是它指向的對象。」 http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python你的lambda捕獲名稱'i',而不是''i'引用的*對象值*。 – Shashank 2015-03-25 01:04:21

回答

9

在此代碼:

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 

確定的i值時,該功能運行 。當函數爲定義的丟失時,值爲i

使用,而不是:

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x, i=i : i*i*x) 

print lambdas[0](1) 
print lambdas[2](1) 

這將產生:

0 
4 

這樣做是因爲,作爲一個特殊的情況下,默認參數的函數,如上面i=i,立即綁定。

+0

關於爲什麼它最初不起作用的解釋會使這是一個很好的答案。但我真的很喜歡默認參數即時綁定。 – Serdalis 2015-03-25 01:11:05

+1

@Serdalis好主意。已添加說明。 – John1024 2015-03-25 01:13:42

6

i4當您的循環結束時,因此i對於每個lambda是4。

如果打印i外循環,你會看到它是4:

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 

print(i) 
4 

您使用的是被整個循環更新的一個變量,如果調用循環,你會得到什麼內部拉姆達你在期待。

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 
    print(lambda x: i * i * x)(1) 
0 
1 
4 
9 
16 

行爲是你所期望的,i只是一個像其他任何變量一樣的變量。

在一個側面說明,你可以使用一個列表比較創建列表:

lambdas = [lambda x,i=i: i * i * x for i in xrange(5)]