Замыкания в Python: почему lambda в цикле возвращают последнее значение
@python_quizРазберем этот квиз
Код в квизе:

Коротко о результате
- При вызове этот фрагмент выведет: [2, 2, 2] [0, 1, 2]
Пояснение — что именно происходит и почему
- В f1 мы создаём список лямбд, каждая из которых возвращает значение переменной i без явной фиксации в момент создания. Все лямбды захватывают одну и ту же переменную i (замыкание по имени). К моменту, когда мы вызываем эти функции, цикл уже завершился, и i имеет последнее значение 2. Поэтому каждая lambda из f1 возвращает 2.
- В f2 используется распространённый идиоматический приём: аргумент по умолчанию
i=i. При создании каждой лямбды текущее значение i присваивается дефолтному параметру функции, то есть фиксируется. В результате каждая лямбда хранит своё значение: 0, 1, 2 соответственно.
Демонстрация (выполните в своём интерпретаторе)

Разбор вариантов (анализ ответов)
- "Выведется: [2, 2, 2] [0, 1, 2]" — совпадает с наблюдаемым поведением. Первый список содержит три одинаковых значения (последнее значение i), второй — фиксированные значения через аргумент по умолчанию.
- "Выведется: [0, 1, 2] [0, 1, 2]" — неверно, потому что без фиксации через аргумент по умолчанию все лямбды в первом списке ссылаются на одну переменную i.
- "Выведется: [2, 2, 2] [2, 2, 2]" — неверно, потому что второй список использует аргумент по умолчанию и фиксирует разные значения.
- "Будет выброшено исключение" — неверно: код корректен и исключений не вызывает.
Альтернативные способы получить фиксированные значения
- Использовать фабрику функций:

- Использовать functools.partial:

Выводы — что запомнить
- Замыкание в Python захватывает переменные по ссылке (имя), а не по значению. Если переменная меняется после создания лямбд, все замыкания увидят её актуальное значение.
- Часто используемый приём для "фиксации" текущего значения — передача его как аргумента по умолчанию (lambda
i=i: i) или создание замыкания через функцию-фабрику. - Этот нюанс — частая ловушка при создании функций в циклах; знание его помогает избежать неожиданных результатов.