def multipliers():
l = []
for i in range(4):
l.append(lambda x : x * i )
return l
>>> ll[0](2)
6
>>> ll[1](2)
6
>>> ll[2](2)
6
>>> ll[3](2)
6
Can you explain the result here? I was hoping to get:
0
2
4
6
def multipliers():
l = []
for i in range(4):
l.append(lambda x : x * i )
return l
>>> ll[0](2)
6
>>> ll[1](2)
6
>>> ll[2](2)
6
>>> ll[3](2)
6
Can you explain the result here? I was hoping to get:
0
2
4
6
The reason for this is that Python’s closures are late binding. This means that the values of variables used in closures are looked up at the time the inner function is called. So as a result, when any of the functions returned by multipliers()
are called, the value of i
is looked up in the surrounding scope at that time. By then, regardless of which of the returned functions is called, the for loop has completed and i
is left with its final value of 3
. Therefore, every returned function multiplies the value it is passed by 3
, so since a value of 2
is passed in the above code, they all return a value of 6
Taken from : http://www.toptal.com/python/interview-questions
The problem is that, as people say, i
is not a local variable of the lambda
.
You have to fix that: using a default parameter value changing during the loop:
>>> def multipliers():
l = []
for i in range(4):
l.append(lambda x, i=i : x * i )
return l
>>> lst = multipliers()
>>> lst[0](2)
0
>>> lst[1](2)
2
>>> lst[2](2)
4
>>> lst[3](2)
6
>>>
The value of i
is not stored inside the lambda
function. That's why you're getting the result you're seeing: Python is using the value of i
it finds when the function is called.