На Python представлен код: 'lst = [lambda i: i*n for n in range(3)]; print([f(2) for f in lst])' Объясните результат и предложите исправление, если поведение не соответствует ожиданиям

27 Мар в 17:15
17 +1
0
Ответы
1
Коротко: проблема — «позднее связывание» (closure захватывает переменную, а не её текущее значение). В вашем коде создаются три лямбды в цикле range(3)\text{range}(3)range(3), но все они используют одну и ту же переменную nnn, которая после цикла равна 222. Поэтому при вызове f(2)f(2)f(2) для каждой функции получается 2⋅2=42\cdot 2=422=4 и выводится [4,4,4][4,4,4][4,4,4].
Почему так: лямбда обращается к имени nnn при выполнении, а не при создании.
Исправления (два простых варианта):
1) Захват значения через параметр по умолчанию:
lst = [lambda i, n=n: i*n for n in range(3)]
print([f(2) for f in lst]) # выводит [0,2,4][0,2,4][0,2,4]
2) Использовать фабрику функций:
def make(n):
return lambda i: i*n
lst = [make(n) for n in range(3)]
print([f(2) for f in lst]) # выводит [0,2,4][0,2,4][0,2,4]
Оба варианта фиксируют текущее значение nnn при создании каждой функции.
27 Мар в 17:47
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир