Понимание словаря с лямбда-функциями дает неправильные результаты
Я попробовал следующий код в Python 3.5.1:
>>> f = {x: (lambda y: x) for x in range(10)}
>>> f[5](3)
9
Очевидно, что это должно возвращать 5
. Я не понимаю, откуда приходит другая ценность, и я ничего не смог найти.
Кажется, что это связано с ссылкой - он всегда возвращает ответ f[9]
, который является последней назначенной функцией.
Какая ошибка здесь и как это сделать, чтобы она работала правильно?
Ответы
Ответ 1
Обзор Python лексический. Закрытие будет ссылаться на имя и область действия переменной, а не на фактический объект/значение переменной.
Что происходит, так это то, что каждая лямбда захватывает переменную x
, а не значение x
.
В конце цикла переменная x
привязана к 9, поэтому каждая лямбда будет ссылаться на это x
, значение которой равно 9.
Почему работает ответ @ChrisP:
make_func
заставляет оценивать значение x
(поскольку оно передается в функцию). Таким образом, лямбда производится со значением x
в настоящее время и мы избегаем вышеуказанной проблемы с охватом.
def make_func(x):
return lambda y: x
f = {x: make_func(x) for x in range(10)}
Ответ 2
Следующее должно работать:
def make_func(x):
return lambda y: x
f = {x: make_func(x) for x in range(10)}
x
в вашем коде заканчивается ссылкой на последнее значение x
, которое равно 9
, но по моему это относится к x
в области функций.