带有lambda函数的字典在Python中的怪异行为 [英] Weird behaviour in python with dict of lambda functions
问题描述
我已经编写了一个用于生成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,程序的输出是随机的.它可以是2
或4
,而我希望只有4
.我不太了解这种行为.
Using Python 3.5.1 on OSX El Capitan, the output of program is random. It can be 2
or 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屋!