problem with lambda / closures

Duncan Booth duncan.booth at invalid.invalid
Mon Nov 30 09:04:16 EST 2009


Louis Steinberg <lou at cs.rutgers.edu> wrote:

>============================== clip here ============
> def p(d):
>      print d
> 
> 
> l=[ ]
> for k in [1,2,3]:
>      l.append(lambda : p(k))
> 
> for f in l:
>      f()
> 
>============================== clip here ============
> I get output
> 3
> 3
> 3
> instead of
> 1
> 2
> 3
> which I would expect.  Can anyone explain this or give me a  
> workaround?  Thank you
> 
There's nothing magic about lambda. The same holds true for any function 
definition.

When you have a function that accesses a variable declared at an outer 
or global scope it always use the value of the variable at the time when 
it is accessed, not the value when it was defined. Your for loop is 
exactly equivalent to:

    def foo(): return p(k)
    l = [ foo, foo, foo ]
    k = 3

where it should be more obvious that you will always get the same 
result.

Try this instead:

    from functools import partial

    l = [ partial(p, k) for k in [1, 2, 3]]


-- 
Duncan Booth http://kupuguy.blogspot.com



More information about the Python-list mailing list