带有lambda函数的字典在Python中的怪异行为 [英] Weird behaviour in python with dict of lambda functions

查看:115
本文介绍了带有lambda函数的字典在Python中的怪异行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个用于生成lambda常数函数字典的函数(它是更复杂的函数的一部分,但我已将其简化为以下代码):

I have written a function for generating a dictionnary of lambda constant functions (it's part of a more complex function but I have simplified it to the code below):

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.我不太了解这种行为.

Using Python 3.5.1 on OSX El Capitan, the output of program is random. It can be 2or 4 while I would expect to have only 4. I don't quite understand this behaviour.

请注意,在python 2.7.10中似乎没有出现错误",并且多次运行该程序时总是得到4.

Note that the "bug" does not seem to occur with python 2.7.10 and I always get 4 when I run the program several times.

是python 3.5.1中的某种bug,还是我错过了明显的东西?

Is it some kind of bug in python 3.5.1 or did I miss something obvious ?

推荐答案

要点是,在lambda函数中已将其定义如下:

The point is that in your lambda function which you have defined it as following :

lambda t: a[key]

您没有使用变量t,而是试图通过将变量key作为字典的键来获取a的值.并在下一次尝试在字典理解范围内包含函数时使用此函数:

You didn't used variable t and tried to get the a's value by passing the variable key as the key to your dictionary. And at the next time which you attempt to use this function in you enclosing function within dictionary comprehension:

{key:f(t) for (key,f) in _interpolators.items()}

每次尝试获取f(t)时,由于t的存在是多余的,因此python尝试通过将变量key传递给a来获取a的值,但它什么也没有与t有关.

Each time that you try to get the f(t), since the existence of t is redundant here python tries to get the a's value by passing the variable key to it, and it has nothing to do with t.

最重要的一点是,您希望python覆盖key变量,因为您在字典理解中使用了key.

And the most important point is, that you expect to python override the key variable because you are using key in your dictionary comprehension.

并且由于lamda对象是python中的函数并且具有其自己的本地名称空间,因此每次尝试返回a[key]时,它都无法访问理解内的迭代变量key,因此由于LEGB方式(lambda)在本地名称空间中查找key,然后将其括起来,一无所获,在全局范围中查找它.

And since lamda object is a function in python and has its own local namespace, each time that it tries to return the a[key] it cant access the iteration variable key inside the comprehension so due to LEGB manner after it (lambda) looks for key in Local namespace and then Enclosing and find nothing, it looks for it in Global scope.

并且由于全局key是以下部分的最后一个迭代变量:

And since the global key is the last iteration variable in following part :

for key in a.keys():
        _interpolators[key] = lambda t: a[key]

lambda函数将其用作key.并且由于在python 3.x中,dict.keys()的顺序是随机的,因此结果也将是随机的.虽然在python 2中不是这样.

The lambda function will use it as the key. And since in python 3.X the order of dict.keys() is randomly, the result would be randomly as well. While it's not like so in python 2.

要解决这个问题,您只需更改您的lambda,如下所示:

And for getting ride of this problem you can simply change your lambda as following:

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"])

这篇关于带有lambda函数的字典在Python中的怪异行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆