lambda semantics in for loop

Andrew McGregor andrew at indranet.co.nz
Sun Jan 5 19:15:41 EST 2003


>>> m=[]
>>> for i in range(10):
...   m.append(lambda x, y=i: x+y)
...
>>> m[0](0)
0
>>> m[1](0)
1
>>> m[2](0)
2
>>> m[0](0,1)
1

In other words, the same way as you do this for ordinary functions.

In python, any variable is an object reference, resolved when the code is 
run.  So in your example, all the i's resolve to the same value.  The body 
of a lambda is only executed at call time, the argument list has to be 
executed at define time, which is why mine works.

Andrew

--On Sunday, January 05, 2003 04:36:39 -0800 Henk Punt <henk at empanda.net> 
wrote:

> Hi,
>
> When I have the following bit of python code:
>
>>>> l = []
>>>> for i in range(10):
> ...     l.append(lambda x: x + i)
>
> I would expect:
>
> l[0](0) = 0
> l[1](0) = 1
>
> l[0](1) = 1
> l[1](1) = 2
>
> etc.
>
> instead
>
> l[0](0) = 9
> l[1](0) = 9
>
> l[0](1) = 10
> l[1](1) = 10
>
> It seems that the 'i' in the lambda binds to the last value of i in the
> for loop.
> Is this because 'i' is really a pointer and not the value of 'i' itself?.
> Please enlighten me!,
>
> How do I modify the example so that I would get my expected semantics.
> Should I copy 'i' to force the creation of a new object?, If so how would
> this work in the case where i is a string. I've tried to coerce python
> into making a deepcopy of a string so that id(s) != id(copy(s)) but I've
> not been able to do that also.
>
> Thanx already,
>
> Henk Punt.
> --
> http://mail.python.org/mailman/listinfo/python-list
>
>







More information about the Python-list mailing list