[英]Weird behaviour in python with dict of lambda functions
我編寫了一個函數來生成lambda常量函數的字典(它是一個更復雜的函數的一部分,但我將它簡化為下面的代碼):
def function(a):
_interpolators = {}
for key in a.keys():
_interpolators[key] = lambda t: a[key]
def _interpolate(t):
return {key:f(t) for (key,f) in _interpolators.items()}
return _interpolate
if __name__ == '__main__':
d = {"foo": 2, "bar":4}
f = function(d)
print(f(0)["bar"])
在OSX El Capitan上使用Python 3.5.1,程序的輸出是隨機的。 它可以是2
或4
而我預計只有4
。 我不太明白這種行為。
請注意,python 2.7.10似乎沒有出現“bug”,而且當我多次運行程序時,我總是得到4
。
它是python 3.5.1中的某種錯誤還是我錯過了一些明顯的東西?
lambda中的key
取自函數function
的范圍。 所以它具有a.keys()
最后一個元素的值。 字典中鍵的順序是任意的,並且由於安全原因,每次運行都會在Python 3中進行更改。 使key
成為lambda的局部變量:
def function(a):
_interpolators = {key: (lambda t, k=key: a[k]) for key in a}
def _interpolate(t):
return {key:f(t) for (key,f) in _interpolators.items()}
return _interpolate
關鍵是你在lambda
函數中定義如下:
lambda t: a[key]
你沒有使用變量t
並試圖通過將變量key
作為字典的鍵來獲取a
的值。 並且在您下次嘗試使用此函數時,您可以在字典理解中包含函數:
{key:f(t) for (key,f) in _interpolators.items()}
每次您嘗試獲取時間f(t)
因為存在t
是多余這里蟒蛇試圖獲得a
通過將變量的值key
給它,它無關t
。
最重要的一點是,你期望python覆蓋key
變量,因為你在字典理解中使用了key
。
並且因為lamda
對象是python中的一個函數並且有自己的本地命名空間,所以每次它嘗試返回a[key]
它都無法訪問理解中的迭代變量key
,所以由於它之后的LEGB方式( lambda
)尋找key
Local命名空間然后Enclosing並找不到任何內容,它在Global scope中查找它。
由於全局key
是以下部分中的最后一個迭代變量:
for key in a.keys():
_interpolators[key] = lambda t: a[key]
lambda
函數將使用它作為key
。 因為在python 3.X中dict.keys()
的順序是隨機的,結果也是隨機的。 雖然在python 2中不是這樣的。
為了解決這個問題,你可以簡單地改變你的lambda
如下:
lambda t: a[t]
在你的代碼中:
def function(a):
_interpolators = {}
for key in a.keys():
_interpolators[key] = lambda t: a[t]
def _interpolate():
return {k:f(k) for k,f in _interpolators.items()}
return _interpolate
if __name__ == '__main__':
d = {"foo": 2, "bar":4}
f = function(d)
print(f()["bar"])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.