Lessons · Python · lambdas look up late
A lambda looks up its variable when it runs
A function made in a loop reads the loop variable when it is called, not when it was created, so every one sees the loop's final value.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
Buttons made in a loop that all open the last tab, callbacks that all log the last id: the classic closure surprise, in Python as in JavaScript.
How to think about it
Freeze the value at creation with a default argument (lambda n=i: n) or a small factory function. If all the callbacks behave like the last one, this is why.
Worked example
fs = [lambda: i for i in range(3)]Three functions, one shared i.
print(fs[0]())2: i is looked up now, and the loop left it at 2.
gs = [lambda n=i: n for i in range(3)]A default is evaluated when the lambda is made.
print(gs[0]())0: frozen.
print([g() for g in gs])[0, 1, 2].
Your turn
Make each handler remember its own index.
handlers = [lambda k=: k for k in range(5)]
Solve one with the tests running
The trap
The default-argument trick means the function accepts an argument it was not meant to. A factory function (def make(i): return lambda: i) is clearer in shared code.