@KIN1991
Python, PHP developer

Как работает позднее связывание в Python?

Всем привет.
Недавно наткнулся на вот такой вот пример.
def multipliers():
  return [lambda x : i * x for i in range(4)]
    
print [m(2) for m in multipliers()] # [6,6,6,6]

В котором я получил достаточно неожиданный ответ(по крайней мере для меня).
Хотелось бы понять как в данном случае применяется позднее связывание?
  • Вопрос задан
  • 1881 просмотр
Пригласить эксперта
Ответы на вопрос 2
@fireSparrow
Чтобы такого не происходило можно сделать так:

def multipliers():
  return [lambda x, i=i: i * x for i in range(4)]
    
print([m(2) for m in multipliers()]) # [0, 2, 4, 6]


или так

def multipliers():
  return (lambda x: i * x for i in range(4))
    
print([m(2) for m in multipliers()]) # [0, 2, 4, 6]


Второй вариант в данном случае мне нравится больше.
Но первый - универсальное решение для всех подобных проблем с лямбдой.
Ответ написан
Комментировать
@Miksarus
Тоже долго ломал голову над этим примером и даже предыдущий ответ не сразу помог мне осознать как всё работает. Дело в том, что i воспринимается как глобальная переменная по отношению к создаваемой лямбда функции, т.е. в лямбде фигурирует не значение i, а ссылка на неё.
После того, как созданы все лямбды, i равна 3. Вот и получаем массив одинаковых значений.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы