Hone

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)]

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.

Practise lambdas look up late on HoneA question on it now, a coding challenge where there is one, and it is remembered for review. Free, no email needed.