Change
lambda: select(b.cat, b.value)
to
lambda b = b: select(b.cat, b.value)
In your original code, b
is not a local variable of the lambda
; it is found in enclosing scope. Once the for-loop
is completed, b
retains it last value. That is why the lambda
functions all use the last button.
If you define the lambda to take one argument with a default value, the default value is determined (and fixed) at the time the lambda is defined. Now b
is a local variable of the lambda
, and when the lambda is called with no arguments, Python sets b
to the default value which happily is set to various different buttons as desired.