Weird closure behavior in python
Solution 1:
As @thg435 points out, a lambda will not encapsulate the values at that moment, but rather the scope. There are too small ways you can address this:
lambda default argument "hack"
[ lambda v=i: v for i in [ 1, 2, 3 ] ]
Or use functools.partial
from functools import partial
[ partial(lambda v: v, i) for i in [ 1, 2, 3 ] ]
Essentially you have to move the scope to be local to the function you are creating. Generally I like using partial
more often since you can pass it a callable, and any args and kargs to create a callable with a proper closure. Internally, it is wrapping your original callable so the scope is shifted for you.
Solution 2:
Closures don't refer to variables but rather to scopes. Since the last value of i
in its scope is '3', all three closures return the same. To "lock" the current value of a variable, create a new scope just for it:
def get() : return [ (lambda x: lambda: x)(i) for i in [ 1, 2, 3 ] ]
for f in get() : print( f() )