can this be done without eval/exec?

Chris Mellon arkanes at gmail.com
Wed Apr 26 21:53:13 EDT 2006


On 4/26/06, Schüle Daniel <uval at rz.uni-karlsruhe.de> 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
>



More information about the Python-list mailing list