I have a following simple code:
def get():
return [lambda: i for i in [1, 2, 3]]
for f in get():
print(f())
As expected from my python knowledge, output is 3 - entire list will contain last value of i
. But how this works internally?
AFAIK, python variables are simply reference to objects, so first closure must enclose object first i
reference - and this object is definitely 1, not 3 O_O. How it happens that python closure encloses variable itself instead of object this variable reference? Does it save variable name as plain text, some "reference to variable" or what?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With