Ну классика же, lambda завязывается на саму переменную, а не на её текущее значение. Т.е. если ты изменишь i, то все лямбды это увидят.
i = 10
f = lambda: print(i)
i = 20
f() # выведет 20
Нужно сохранить искомое значение в самой лямбде. Самый простой способ - вот такой хак:
i = 10
# сохраняем глобальную i как значение по умолчанию параметра i
f = lambda i=i: print(i)
i = 20
f() # выведет 10
f(30) # выведет 30
Как видишь последний вызов работает немножко не так, как мы ожидаем - а ожидаем мы ошибку из-за лишнего параметра. Но можно схитрить так:
i = 10
# сохраняем глобальную i как значение по умолчанию параметра i
# Параметр i может быть передан только по имени: i=30
f = lambda *,i=i: print(i)
i = 20
f() # выведет 10
f(i=30) # выведет 30
f(30) # TypeError: <lambda>() takes 0 positional arguments but 1 was given