• lambda
  • tkinter
  • callback

This situation is commonly encountered when creating callback functions in a loop. The OP expects the loop variable used in their callback lambdas to have the value it had when the function was created, instead it has the current value at calling time, typically, the last value of the loop variable. The solution is to bind the loop variable as a default arg.

There’s a good explanation of this in the official Python FAQ: Why do lambdas defined in a loop with different values all return the same result?