Рассмотрите этот Python-кейс: "funcs = [lambda: i for i in range(3)]; print([f() for f in funcs])" — объясните результат и предложите варианты, как получить ожидаемое [0,1,2]

29 Дек 2025 в 07:15
16 +1
1
Ответы
1
Результат — [2,2,2][2,2,2][2,2,2]. Почему: лямбда-функции замыкают переменную iii по ссылке (late binding), а не её текущее значение. После завершения цикла переменная iii равна последнему значению итерации (222), поэтому при вызове каждой лямбды берётся это значение.
Варианты получения ожидаемого [0,1,2][0,1,2][0,1,2]:
1) Захват значения через аргумент по умолчанию
```
funcs = [lambda i=i: i for i in range(333)]
print([f() for f in funcs]) # -> [0,1,2][0,1,2][0,1,2] ```
2) Фабричная функция (замыкаем переданный параметр)
```
def make(j):
return lambda: j
funcs = [make(i) for i in range(333)]
print([f() for f in funcs]) # -> [0,1,2][0,1,2][0,1,2] ```
3) Немедленно вызываем лямбду, возвращающую другую лямбду
```
funcs = [(lambda x: (lambda: x))(i) for i in range(333)]
print([f() for f in funcs]) # -> [0,1,2][0,1,2][0,1,2] ```
4) Использовать functools.partial
```
from functools import partial
funcs = [partial(lambda x: x, i) for i in range(333)]
print([f() for f in funcs]) # -> [0,1,2][0,1,2][0,1,2] ```
Любой из этих подходов сохраняет текущее значение iii при создании каждой функции.
29 Дек 2025 в 07:23
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир