Scott David Daniels wrote:
Denis Kasak wrote:
...
spam = []
for i in range(10):
...   spam.append(lambda: i)
spam[0]()
9
spam[1]()
9

Manually creating the lambdas and appending them to a list works as
expected, naturally; I don't see a good reason why it wouldn't work
with a loop. Am I missing something?

Yes, you are missing something: binding time.  your anonymous function
returns the value of "i" in the enclosing scope _at_the_time_of_
_the function's_execution_.  If you follow your previous example with
'del i' and then execute any of your spam functions, you'll get an
"NameError: global name 'i' is not defined".

Ah, the problem was in the subtle misunderstanding of the semantics of lambda functions on my part. It's much clearer now. Thanks.

There are a couple of ways to slve your problem:
(1) use default args to do the binding at the function definition time.
    for i in range(10):
        spam.append(lambda arg=i: arg)
The lambda expression is normally spelled "lambda i=i: i)", but if you
don't know the idiom, I find the "i=i" part confuses people.

Indeed. It hasn't occured to me that lambdas could bind the variables inside them by name. I guess my lambdas are still a little shaky. :-)

--
Denis Kasak
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to