Nicolas Rougier Nicolas Rougier - 4 years ago 153
Python Question

Weird behaviour in python with dict of lambda functions

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


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.

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.

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

Answer Source

key in the lambda is taken from the scope of the function function. So it has the value of the last element in a.keys(). The order of keys in a dictionary is arbitrary and changes in Python 3 for each run, due to security reasons. Make key a local variable of the 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
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download