Лямбда-функция не выполняется в словаре со значениями "if-else"

Я пытаюсь определить различные лямбда-функции в словаре 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. Просто используйте a() if condition else b()

bigbounty 28.05.2019 18:45

Лучше читать дальше lambda functions. w3schools.com/python/python_lambda.asp

bigbounty 28.05.2019 18:46

@bigbounty Я не думаю, что это сделает то же самое: если я не ошибаюсь, будут выполнены все строки словаря.

MarcOnFire 28.05.2019 18:48

@bigbounty Я думаю, что ОП пытается добиться чего-то вроде ленивой оценки. Так что это не сработает

rdas 28.05.2019 18:49

Лямбды здесь не нужны

bigbounty 28.05.2019 18:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
638
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Здесь возникает проблема из-за приоритета оператора. Вам нужно заключить в скобки 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'))()

Другие вопросы по теме