Consider the following code:
def A():
l = list()
for i in range(5):
l.append(lambda: i)
return l
for f in A():
print( f() )
It prints out 4
five times, and I'm assuming it does that because the lambda function has taken the variable i
through the outer scope of A
, but right before the moment the variable became out of scope.
Then we have this code:
def B():
l = list()
for i in range(5):
l.append((lambda i: lambda: i)(i))
return l
for f in B():
print( f() )
It prints out all numbers from 0 to 4 in order. I am assuming it does that because the variable i
has been grabbed from the scope of the outer lambda which took it as a parameter, so the value has been assigned to the cell in the moment when that external lambda finished executing.
But what if i
held a mutable object instead of an immutable int
?
def C():
l, i = list(), list()
for r in range(5):
i.append(r)
l.append((lambda i: lambda: i)(i.copy()))
return l
for f in C():
print( f() )
It does print out the lists in order as expected, because I used the list.copy()
method in the argument.
Now, is my understanding correct?
If so, then is there a more pythonic or simpler way to save in a closure cell either an immutable object (or a copy of a mutable object), at the exact moment I want to? In other words, is there a better way than the (lambda i: lambda: i)(i)
latch I came up with?