Behaviour I don't understand in Python mixings comprehension lists and lambda-functions -


this question has answer here:

i don't understand behaviour of piece of code, involving comprehension list on lambda functions call method in different objects. happened in large program, question made nonsensical toy-case show 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) ev in (ev1, ev2, ev3)]     print([f(0.5) f in funcs]) 

the output [6.6, 6.6, 6.6], means method in ev3 1 being evaluated time. instead of [2.6, 4.6, 6.6], have expected. surprises me if rid of lambda-function, behaviour 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 ev in (ev1, ev2, ev3)]     print([f(0.5) f in funcs]) 

returns [2.5, 4.5, 6.5]. can explain going on here? , how should code in pythoninstic way?

the problem ever evaluating ev at time call function. thus, it's using whatever value ev has when start print statement. of course, time ev has value of last function in list.

this no different if had done this:

funcs = [lambda x: ev.eval(x+0.1),          lambda x: ev.eval(x+0.1),          lambda x: ev.eval(x+0.1)] 

notice how use ev, , use same ev @ time run functions.

to want, need bind ev current value in list comprehension @ time define comprehension, can passing in value through lambda arguments:

funcs = [lambda x, ev=ev: ev.eval(x+0.1) ev in (ev1, ev2, ev3)] 

however, suggest not this. have experienced, such code hard understand , debug. win no points cramming functionality single line possible.

the technical term closure. more information, check out question on stackoverflow: why aren't python nested functions called closures?


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -