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]()
10
x 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.html


I 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]

- Robert

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

Reply via email to