Robert Bradshaw wrote:
On Jan 5, 2010, at 1:47 PM, Jason Grout wrote:Dag Sverre Seljebotn wrote:Jason Grout wrote:I'm trying to generate a list of functions where each function returns its place in a list. Here is my code:cc=[(lambda: x) for x in [1..2]] However, I have: cc[0]() returns 2 (but I want it to return 1) cc[1]() returns 2 (correctly)Does anyone know what is going on here? It seems like all the functions just end up being the last function!Py> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'y' is not defined Py> cc=[(lambda: x) for x in range(2)] Py> x=10 Py> cc[0]() 10x is declared by Python as a variable in the enclosing scope (the function containing that line you wrote). So all the functions returns the same variable.Declare a new function which returns the lambda and you're good.I vaugely remember this behaviour being changed in Python 3, although it might only have been for generator expressions..Ah, I see. I was confused by scoping rules in python. I just found this post, which discusses the problem in detail:http://lackingrhoticity.blogspot.com/2009/04/python-variable-binding-semantics-part.htmlI like the double-lambda solution: sage: cc=[(lambda y: lambda: y)(x) for x in [1..5]] sage: [c() for c in cc] [1, 2, 3, 4, 5]
Personally, I found Minh's solution much more readable than that, though it might be slower.
def func(x):
return lambda: x
cc = map(func, xrange(10)) # or I suppose [func(x) for x in xrange(10)]
Thanks,
Jason
-- To post to this group, send an email to [email protected] To unsubscribe from this group, send an email to [email protected] For more options, visit this group at http://groups.google.com/group/sage-devel URL: http://www.sagemath.org
