can this be done without eval/exec?
Schüle Daniel
uval at rz.uni-karlsruhe.de
Thu Apr 27 16:14:15 EDT 2006
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
More information about the Python-list
mailing list