2016-04-23 93 views
16

我嘗試在Python 3.5.1以下代碼:與lambda函數解釋的理解給出了錯誤的結果

>>> f = {x: (lambda y: x) for x in range(10)} 
>>> f[5](3) 
9 

很明顯,這應該返回5。我不明白其他價值來自哪裏,我無法找到任何東西。

它看起來像是與參考相關的東西 - 它總是返回f[9]的答案,這是分配的最後一個函數。

這裏有什麼錯誤,應該怎麼做才能正常工作?

回答

14

Python範圍是詞法。閉包將引用變量的名稱和範圍,而不是變量的實際對象/值。

會發生什麼是每個lambda捕獲變量x而不是x

在循環變量x勢必9月底,因此每個拉姆達將把這個x,其值是9

爲什麼@ ChrisP的回答工作:

make_func強制對x的值進行評估(因爲它將 傳遞給函數)。因此,拉姆達的值爲x,目前爲 ,我們避免了上述範圍問題。

def make_func(x): 
    return lambda y: x 

f = {x: make_func(x) for x in range(10)} 
+7

一種替代速記將'F = {X:(拉姆達Y,X = X:X),用於在範圍X(10)}',因爲函數默認參數在定義的時間限制,所以他們會綁定'x'的_value_,而不是_name_'x'。 – ShadowRanger

+0

這可能聽起來像一個非常愚蠢的問題(我對lambda不太熟悉),但make_func(x)如何工作?我可以想象f [5](3)意味着 - > f = {5:make_func(5)}。那麼make_func(5)(3)如何等於5? – Adib

+1

詞典理解使得整數的字典鍵成爲函數的值。 f [5]返回鍵入5的字典中的值,它恰好是函數lambda:x。請注意,lambda忽略在(y)中傳遞的任何內容,並始終返回x。這就是爲什麼lambda將返回5或9(由於上述問題)。 – gnicholas

6

下面應該工作:

def make_func(x): 
    return lambda y: x 

f = {x: make_func(x) for x in range(10)} 

x在你的代碼最終指的是最後x價值,這是9,但在我它是指x的功能範圍。