2

I have an array of functions, for example:

>>> def f():
...     print "f"
... 
>>> def g():
...     print "g"
... 
>>> c=[f,g]

Then i try to create two lambda functions:

>>> i=0
>>> x=lambda: c[i]()
>>> i+=1
>>> y=lambda: c[i]()

And then, call them:

>>> x()
g
>>> y()
g

Why c[i] in lambda are the same?

1
  • The easy way to solve this problem is to just not create the useless lambdas in the first place. Just replace those two lines with x = c[i] and y = c[i], and you will get exactly the functions you wanted. The only reason to ever write lambda: f() instead of f is to stick f into a closure namespace to look it up later, instead of just using it. You don't want to do that here, and in fact that's exactly what's causing your problem. Commented May 26, 2013 at 23:15

2 Answers 2

10

That's because the lambda function is fetching the value of the global variable i at runtime:

>>> i = 0
>>> x=lambda z = i : c[z]() #assign the current value of `i` to a local variable inside lambda
>>> i+=1
>>> y =lambda z = i : c[z]()
>>> x()
f
>>> y()
g

A must read: What do (lambda) function closures capture?

Sign up to request clarification or add additional context in comments.

1 Comment

Note: the accepted answer for the linked question shows how to make the desired name capture happen (see the createAdder function at the end of stackoverflow.com/a/2295368/25050.
3

In Python closures don't capture actual values, but instead they capture namespaces. So when you use i inside your function it's actually looked up in the enclosing scope. And the value there has already changed.

You don't need all those lambdas and lists to see this.

>>> x = 1
>>> def f():
...   print(x)
...
>>> x = 2
>>> def g():
...   print(x)
...
>>> g()
2
>>> f()
2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.