Дан фрагмент Python: "def make_funcs(): return [lambda x: i * x for i in range(3)]" — что вернёт вызов make_funcs()[0](2) и почему; как исправить замыкание, сохранив короткость кода?
Вызов вернёт 444. Почему: list-comprehension создаёт три лямбды, но они захватывают переменную iii по ссылке. После завершения цикла iii равно 222, поэтому все лямбды вычисляют 2⋅x2 \cdot x2⋅x и при вызове с x=2x=2x=2 дают 2⋅2=42\cdot2=42⋅2=4. Короткое исправление — привязать текущее значение iii как значение параметра по умолчанию: ```python def make_funcs(): return [lambda x, i=i: i * x for i in range(3)] ``` Тогда `make_funcs()[0](2)` вернёт 000; три функции при x=2x=2x=2 дадут 0, 2, 40,\,2,\,40,2,4.
Почему: list-comprehension создаёт три лямбды, но они захватывают переменную iii по ссылке. После завершения цикла iii равно 222, поэтому все лямбды вычисляют 2⋅x2 \cdot x2⋅x и при вызове с x=2x=2x=2 дают 2⋅2=42\cdot2=42⋅2=4.
Короткое исправление — привязать текущее значение iii как значение параметра по умолчанию:
```python
def make_funcs():
return [lambda x, i=i: i * x for i in range(3)]
```
Тогда `make_funcs()[0](2)` вернёт 000; три функции при x=2x=2x=2 дадут 0, 2, 40,\,2,\,40,2,4.