2

Я создаю один лайнер, чтобы отобразить строку int для проверки функции, если значения совпадают. В идеале, словарь результатов d ведет себя как d['0'](0) is True и d['0'](1) is False. Но вместо этого я получаю следующий вывод:Понимание словаря с помощью выражения лямбда не дает желаемого результата

>>> d = { str(i): lambda v: v == i for i in range(3) } 
>>> d['0'](0) 
False 
>>> d['0'](2) 
True 

Я предполагаю, что причина - ленивая оценка. Я думаю, что я мог бы построить словарь с нулевым циклом for, но вместо этого я хочу использовать однострочное выражение.

Может ли кто-нибудь объяснить, почему этот подход не удается и как я это делаю правильно?

+1

также посмотреть на: http://docs.python-guide.org/en/latest/writing/gotchas/#late-binding-closures – moooeeeep

+0

На самом деле не имеет ничего общего с ленивой оценкой, как работает пространство имен функций в Python. – zehnpaard

+0

Правильный термин: _late binding_. Разумеется, хороший ответ будет касаться этого. – moooeeeep

ответ

4

Вам необходимо записать текущее значение i для каждой лямбда, которое может быть выполнено с помощью аргумента по умолчанию i=i. См.:

>>> d = { str(i): lambda v, i=i: v == i for i in range(3) } 
>>> d['0'](0) 
True 
>>> d['0'](2) 
False 
0

Просто альтернативный метод, позволяющий более логично видеть вещи.
d=dict((str(i),lambda v, i=i: v==i) for i in range(3))

это даст те же результаты, как и выше