Because the i
in the lambda is probably not what you expect. To verify this, change the code:
acts.append(lambda x: (i, i ** x))
Now the print
tells you the value of i
:
(4, 16)
(4, 16)
(4, 16)
(4, 16)
(4, 16)
This means that the lambda
doesn't copy the value of i
but keeps a reference to the variable, so all lambda
s see the same value. To fix this, copy i
:
acts.append(lambda x, i=i: (i, i ** x))
The little i=i
creates a local copy of i
inside the lambda
.
[EDIT] Now why is this? In the versions of Python before 2.1, local functions (i.e. functions defined inside of other functions) couldn't see the variables in the same scope.
def makeActions():
acts=[]
for i in range(5):
print len(acts)
def f(x): # <-- Define local function
return i ** x
acts.append(f)
print acts[i]
return acts
then you'd get an error that i
isn't defined. lambda
could see the enclosing scope at the cost of a somewhat wierd syntax.
This behavior has been fixed in one of the recent versions of Python (2.5, IIRC). With these old versions of Python, you'd have to write:
def f(x, i=i): # <-- Must copy i
return i ** x
Since the fix (see PEP 3104), f()
can see variables in the same scope, so lambda
isn't necessary anymore.