I don't understand the behaviour of a piece of code, involving a comprehension list over lambda functions that call a method in different objects. It happened in a large program, so for this question I made a nonsensical toy-case to show my point:
class Evaluator(object):
def __init__(self, lft, rgt):
self.lft = lft
self.rgt = rgt
def eval(self, x):
return self.lft + x * (self.rgt - self.lft)
if __name__ == "__main__":
ev1 = Evaluator(2, 3)
ev2 = Evaluator(4, 5)
ev3 = Evaluator(6, 7)
funcs = [lambda x:ev.eval(x+0.1) for ev in (ev1, ev2, ev3)]
print([f(0.5) for f in funcs])
The output I get is [6.6, 6.6, 6.6]
, which means that it is the method in ev3
the one that is being evaluated all the time. Instead of [2.6, 4.6, 6.6]
, as I would have expected. But what really surprises me is that if I get rid of the lambda-function, the behaviour is fine:
class Evaluator(object):
def __init__(self, lft, rgt):
self.lft = lft
self.rgt = rgt
def eval(self, x):
return self.lft + x * (self.rgt - self.lft)
if __name__ == "__main__":
ev1 = Evaluator(2, 3)
ev2 = Evaluator(4, 5)
ev3 = Evaluator(6, 7)
funcs = [ev.eval for ev in (ev1, ev2, ev3)]
print([f(0.5) for f in funcs])
returns [2.5, 4.5, 6.5]
. Can anyone explain what is going on here? And how should I code this in a Pythoninstic way?