Подтвердить что ты не робот

Сжатие инструкции `x if x else y` в Python

Я знаком с тройным оператором Python:

value = foo if something else bar

Мой вопрос очень прост: без предварительных назначений, все равно нужно ссылаться на термин, который оценивается в (if ...), из одного из возвращаемых операндов (... if или else ...)?

Мотивация здесь в том, что иногда я использую выражения в if ..., которые именно то, что я хотел бы иметь в результате тройной операции; бывает, хотя для небольших выражений нет проблем, повторяющих его, но для немного более длинных выражений это выглядит несколько неприятно. Возьмем это как пример:

value = info.findNext("b") if info.findNext("b") else "Oompa Loompa"
4b9b3361

Ответ 1

Нет никакого способа сделать это, и это намеренно. Тернар, если предполагается, только для тривиальных случаев.

Если вы хотите дважды использовать результат вычисления, поместите его во временную переменную:

value = info.findNext("b")
value = value if value else "Oompa Loompa"

Как только вы это сделаете, становится ясно, что вы делаете что-то глупое, и на самом деле питонический способ написать это:

value = info.findNext("b")
if not value:
    value = "Oompa Loompa"

И это на самом деле на 5 меньше нажатий клавиш, чем ваша первоначальная попытка.

Если вы действительно хотите сохранить нажатия клавиш, вы можете сделать это:

value = info.findNext("b") or "Oompa Loompa"

Но это обескуражено многими руководствами по стилям и BDFL.

Если вы делаете это только один раз, лучше быть более явным. Если вы делаете это полдюжины раз, это тривиально - и намного лучше - сделать findNext для необязательного по умолчанию возврата вместо None, как и все эти встроенные и stdlib-функции:

def findNext(self, needle, defvalue=None):
    # same code as before, but instead of return None or falling off the end,
    # just return defvalue.

Затем вы можете сделать это:

value = info.findNext("b", "Oompa Loompa")

Ответ 2

Не используйте if ... else вообще. Вместо этого воспользуйтесь операторами коалесцирования Python.

value = info.findNext("b") or "Oompa Loompa"