Re: can this be done without eval/exec?
Schüle Daniel wrote: and now the obvious one (as I thought at first) lst=[] for i in range(10): ... lst.append(lambda:i) ... lst[0]() 9 i 9 I think I understand where the problem comes from lambda:i seems not to be fully evalutated it just binds object with name i and not the value of i thus lst[0]() is not 0 The problem is that variables in closures are not bound until the variable goes out of scope. So each lambda is bound to the final value of i. are there other solutions to this problem without use of eval or exec? The workaround is to use a default argument to bind the current value of i: In [1]: lst = [] In [2]: for i in range(10): ...: lst.append(lambda i=i: i) ...: ...: In [3]: lst[0]() Out[3]: 0 In [4]: lst[5]() Out[4]: 5 A list comp makes this IMO cleaner: In [5]: lst = [ lambda i=i: i for i in range(10) ] In [6]: lst[0]() Out[6]: 0 In [7]: lst[5]() Out[7]: 5 Kent -- http://mail.python.org/mailman/listinfo/python-list
Re: can this be done without eval/exec?
Kent Johnson schrieb: Schüle Daniel wrote: and now the obvious one (as I thought at first) lst=[] for i in range(10): ... lst.append(lambda:i) ... lst[0]() 9 i 9 I think I understand where the problem comes from lambda:i seems not to be fully evalutated it just binds object with name i and not the value of i thus lst[0]() is not 0 The problem is that variables in closures are not bound until the variable goes out of scope. So each lambda is bound to the final value of i. are there other solutions to this problem without use of eval or exec? The workaround is to use a default argument to bind the current value of i: In [1]: lst = [] In [2]: for i in range(10): ...: lst.append(lambda i=i: i) ...: ...: In [3]: lst[0]() Out[3]: 0 In [4]: lst[5]() Out[4]: 5 A list comp makes this IMO cleaner: In [5]: lst = [ lambda i=i: i for i in range(10) ] In [6]: lst[0]() Out[6]: 0 In [7]: lst[5]() Out[7]: 5 Kent many thanks for the explaination, it look much simpler than my solutions too Daniel -- http://mail.python.org/mailman/listinfo/python-list
can this be done without eval/exec?
Hello group, lst=[] for i in range(10): ... lst.append(eval(lambda:%i % i)) ... lst[0]() 0 lst[1]() 1 lst[9]() 9 lst=[] for i in range(10): ... exec tmp = lambda:%i % i # assignment is not expression ... lst.append(tmp) ... lst[0]() 0 lst[1]() 1 lst[9]() 9 and now the obvious one (as I thought at first) lst=[] for i in range(10): ... lst.append(lambda:i) ... lst[0]() 9 i 9 I think I understand where the problem comes from lambda:i seems not to be fully evalutated it just binds object with name i and not the value of i thus lst[0]() is not 0 are there other solutions to this problem without use of eval or exec? Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: can this be done without eval/exec?
On 4/26/06, Schüle Daniel [EMAIL PROTECTED] wrote: Hello group, lst=[] for i in range(10): ... lst.append(eval(lambda:%i % i)) ... lst[0]() 0 lst[1]() 1 lst[9]() 9 lst=[] for i in range(10): ... exec tmp = lambda:%i % i # assignment is not expression ... lst.append(tmp) ... lst[0]() 0 lst[1]() 1 lst[9]() 9 and now the obvious one (as I thought at first) lst=[] for i in range(10): ... lst.append(lambda:i) ... lst[0]() 9 i 9 I think I understand where the problem comes from lambda:i seems not to be fully evalutated it just binds object with name i and not the value of i thus lst[0]() is not 0 are there other solutions to this problem without use of eval or exec? Using a factory function closures instead of lambda: def maker(x): ... def inner_maker(): ... return x ... return inner_maker ... lst = [] for i in range(10): ... lst.append(maker(i)) ... lst[0]() 0 lst[5]() 5 lst[9]() 9 Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: can this be done without eval/exec?
are there other solutions to this problem without use of eval or exec? Using a factory function closures instead of lambda: def a(x): ... def b(): ... return x ... return b ... lst=[] for i in range(10): ... lst.append(a(i)) ... lst[0]() 0 lst[1]() 1 lst[9]() 9 yes this works I was playing a little more with this idea and got into the next trouble :) cnt=0 def a(): ... def b(): ... return cnt ... global cnt ... cnt += 1 ... return b ... lst=[] for i in range(10): ... lst.append(a()) ... lst[0]() 10 lst[1]() 10 I figured out what was wrong, here is corrected version cnt = 0 def a(): ... global cnt ... tmp = cnt ... def b(): ... return tmp ... cnt += 1 ... return b ... lst=[] for i in range(10): ... lst.append(a()) ... lst[0]() 0 lst[1]() 1 Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list