簡體   English   中英

python中奇怪的行為與la​​mbda函數的dict

[英]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,程序的輸出是隨機的。 它可以是24而我預計只有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM