Лямбда-функция не выполняется в словаре со значениями if-else - PullRequest
0 голосов
/ 28 мая 2019

Я пытаюсь определить различные лямбда-функции в словаре 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.

Кто-то может объяснить мне, почему определение, возвращенное в первом случае, не работает?

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 28 мая 2019

Ваши лямбды:

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'))()
1 голос
/ 28 мая 2019

Код, который вы написали, эквивалентен:

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'))()
0 голосов
/ 28 мая 2019

Здесь есть проблема из-за приоритета оператора. Вам необходимо заключить в скобки 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...>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...