Я пытаюсь определить различные лямбда-функции в словаре Python. Я знаю, что, вероятно, лучше всего иметь только одну лямбда-функцию в части «значение» элемента словаря и управлять подслучаями внутри определяемой функции, но, тем не менее, я не понимаю, почему этот код не работает так, как я хочу :
def a():
print('a')
def b():
print('b')
def c():
print('c')
def d():
print('d')
condition = True
dict = {
'foo': lambda: a() if condition else lambda: b(),
'bar': lambda: c() if condition else lambda: d()
}.get('foo', lambda: print('not found'))()
если мы установим условие = False, код не будет печатать b, он ничего не сделает (кажется)..почему? Вместо этого, если мы попробуем использовать словарь без определений лямбда-функций, он, похоже, будет работать так, как я ожидаю:
dict2 = {
'foo': 4 if condition else 5,
'bar': 6 if condition else 7
}.get('foo', -1)
dict2 будет 5.
Кто-нибудь может объяснить мне, почему определение, возвращенное в первом случае, не работает?
Заранее спасибо!
Лучше читать дальше lambda functions
. w3schools.com/python/python_lambda.asp
@bigbounty Я не думаю, что это сделает то же самое: если я не ошибаюсь, будут выполнены все строки словаря.
@bigbounty Я думаю, что ОП пытается добиться чего-то вроде ленивой оценки. Так что это не сработает
Лямбды здесь не нужны
Здесь возникает проблема из-за приоритета оператора. Вам нужно заключить в скобки lambdas
:
(lambda: a()) if condition else (lambda: b())
Что делает ваш код:
lambda: (a() if condition else lambda: b())
Что создает функцию, которая либо возвращает a()
, либо возвращает другая функция, которая возвращает b()
.
Заключив в скобки каждый lambda
, вы получите правильное выполнение: либо функция, возвращающая a()
, либо функция, возвращающая b()
Если condition
равно False
, ваш вызов функции фактически возвращает это:
<function <lambda>.<locals>.<lambda> at 0x...>
Ваши лямбды:
lambda: a() if condition else lambda: b()
На самом деле:
(lambda: a() if condition else (lambda: b()))
Итак, если condition == False
, вы возвращаете лямбду, если True
- вы используете a()
В любом случае, лямбды здесь излишни. Вы можете заменить его на:
dict_ = {
'foo': a if condition else b,
'bar': c if condition else d
}.get('foo', lambda: print('not found'))()
Код, который вы написали, эквивалентен:
def a():
print('a')
def b():
print('b')
def c():
print('c')
def d():
print('d')
condition = True
dict = {
'foo': lambda: (a() if condition else lambda: b()),
'bar': lambda: (c() if condition else lambda: d())
}.get('foo', lambda: print('not found'))()
Это означает, что код после первой лямбды считается одним блоком функции. Что вы хотите:
def a():
print('a')
def b():
print('b')
def c():
print('c')
def d():
print('d')
condition = True
dict = {
'foo': (lambda: a()) if condition else (lambda: b()),
'bar': (lambda: c()) if condition else (lambda: d())
}.get('foo', lambda: print('not found'))()
Не используйте
lambda
. Просто используйтеa() if condition else b()