[Giovanni Bajo] >> >>> a = [] >> >>> for i in range(10): >> >> ... a.append(lambda: i) >> ... >> >> >>> print [x() for x in a] >> >> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9] >> >> This subtle semantic of lambda is quite confusing, and still forces people to >> use the "i=i" trick.
[Greg Ewing] > This has *nothing* to do with the semantics of lambda! > It's because Python's for-loop doesn't put its control > variable in a new scope, the way Scheme's equivalent > construct does. I don't think I follow that. Scheme has no loops in Python's sense -- things like "do" are shorthand for expressing stylized recursion, where each conceptual iteration gets a fresh set of "loop variables". When people talk about giving a Python for-loop vrbl its own scope, they generally don't mean a new scope on _each iteration_, they just mean that, e.g., i = 5 for i in range(10): # do stuff print i prints 5 intead of 9, about the same as creating a nested block with its own autos in C. The Scheme way is more like: i = 5 def step(i): # do stuff if i < 9: step(i+1) step(0) print i except with tail-recursion elimination. That also prints 5, but does a hell of a lot more than _just_ arrange for that. > *That's* what needs to be addressed to fix this problem. > I've made a suggestion about that before, but Guido > rejected it, so I won't repeat it here. Don't recall what that was, but creating a new scope on each iteration sounds hard to explain in Python. If Giovanni wants the Scheme way ;-), it's available: """ a = [] def step(i): a.append(lambda: i) if i < 9: step(i+1) step(0) print [x() for x in a] """ prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], although it's more sanely written in Python with a loop: """ def make_lambda(i): return lambda: i a = [] for i in range(10): a.append(make_lambda(i)) print [x() for x in a] """ Abusing the default-argument machinery to capture current bindings is never necessary, and _is_ abuse. Of course I do it too -- but rarely :-) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com