The point is that in your lambda
function which you have defined it as following :
lambda t: a[key]
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()}
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
.
And the most important point is, that you expect to python override the key
variable because you are using key
in your dictionary comprehension.
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.
And since the global key
is the last iteration variable in following part :
for key in a.keys():
_interpolators[key] = lambda t: a[key]
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.
And for getting ride of this problem you can simply change your lambda
as following:
lambda t: a[t]
And in your code :
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"])