Тернарный оператор Python без else

85

Можно ли сделать это в одной строке в Python?

if <condition>:
    myList.append('myString')

Я пробовал тернарный оператор:

myList.append('myString' if <condition>)

но моей IDE ( MyEclipse ) он не понравился без else.

JCB
источник
1
Вы имеете в виду тернарный оператор, не состоящий из трех частей? Разве это не противоречие в терминах?
user207421 03 нояб.2020,

Ответы:

119

Да, ты можешь это сделать:

<condition> and myList.append('myString')

Если <condition>ложно, тогда произойдет короткое замыкание, и правая сторона не будет оцениваться. Если <condition>истинно, тогда правая часть будет оценена, и элемент будет добавлен.

Я просто отмечу, что выполнение вышеизложенного не является питоническим, и, вероятно, было бы лучше написать это, независимо от того:

if <condition>: myList.append('myString')

Демонстрация:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']
Клаудиу
источник
10
Хотя этот ответ технически верен, это плохая практика программирования. Поскольку Python стремится быть языком, который легко читается, этот код будет считаться непитоническим.
Мистер Лэнс Э Слоан
10
@LS: Я согласен, поэтому я сказал, что, вероятно, было бы лучше просто использовать оператор if. Но я немного изменил ответ, чтобы было понятнее.
Claudiu
2
fyi, второй пример не пройдёт проверку pep8: E701 multiple statements on one lineзначит, тоже не питонический ...;)
Cas
1
@hard_working_ant «правильный» путь был бы x = object.get('attribute')в этом случае
wihlke
1
@wihlke: yes и далее добавление x = object.get ('attribute', None) по умолчанию в None
hard_working_ant
45

Причина, по которой язык не позволяет использовать синтаксис

variable = "something" if a_condition

без elseэтого, в случае, когда a_condition == False, variableвнезапно неизвестно. Возможно, это может быть по умолчанию None, но Python требует, чтобы все назначения переменных действительно приводили к явным назначениям. Это также относится к таким случаям, как ваш вызов функции, поскольку значение, переданное функции, оценивается так же, как RHS оператора присваивания.

Точно так же все returns должны фактически возвращаться, даже если они условны return. Например:

return variable if a_condition

не допускается, но

return variable if a_condition else None

разрешено, поскольку второй пример гарантированно что-то возвращает.

Эммет Батлер
источник
1
По иронии судьбы, Python не позволяет нам использовать это, так что переменная никогда не бывает нулевой, но все же variable=Noneявляется совершенно законной. : D
Парень
1
Но я хотел использовать это так: continue if i == 0в цикле for.
karantan
2
Вы можете делатьelse pass?
OldBunny2800
5
else passне работает, потому что тернарное выражение должно возвращать значение, которое можно передать return. passне является допустимым returnзначением.
Эммет Батлер
4
Я не согласен , что эта мотивация является реальной причиной, учитывая , что if a_condition: variable = "something"и if a_condition: return variableзаконны. Таким образом, это, по сути, произвольный синтаксический выбор python.
oulenz
13
if <condition>: myList.append('myString')

В противном случае нет. Зачем нужно ставить в одну строчку?

Обратите внимание, что «тернарный оператор» - это оператор . Как и любой оператор, он должен что-то возвращать , так как же у вас может быть тернарный оператор без elseпредложения? Что он должен вернуть, если условие не соответствует истине?

мгильсон
источник
10

Вы в основном запрашиваете do_thing() if <condition> else passконструкцию (которая бросит SyntaxError, если запустится). Как я обнаружил во время исследования (в некоторой степени) подобный вопрос do_thing() if condition else None настолько близок, насколько вы можете получить (это просто еще один способ сделать <condition> and do_thing()). Итак, чтобы обобщить эту идею и другие ответы, вот ваши варианты:

  • if <condition>: myList.append('myString') - кажется наименее хакерским (и, следовательно, предпочтительным) способом
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

источник
Наименее хакерский способ не работает. По крайней мере, в REPL - возникает синтаксическая ошибка. Похоже, это вызвано предыдущим кодом в той же строке. Вместо этого это нужно выполнить в отдельной строке. Но даже в этом случае требуется ввод пользователя, чтобы пропустить многоточие.
Unknow0059
3

myList.extend(['myString'] if condition else []) тоже будет работать, хотя это больше работы, чем другие решения.

Джейк Бизингер
источник
0

Вы можете сделать что-то вроде этого:

myList.append('myString') if <condition> else False

или же

myList.append('myString') if <condition> else 0
Захари Кьодини
источник
Ложь и 0 не добавляются в список. Строке просто нужно что-то вернуть, если условие не выполняется. Вы можете заменить 0 или False на None или пустую строку, или что угодно, и это не повлияет на список.
Zachary Chiodini
Я думаю, что в то время я думал о понимании списка. Мой комментарий удален, против не был я. Я полагаю, что более чистый способ - это сделать. myList.append('myString') if True else _Но если вы ничего не назначаете, не имеет значения. Я обеспокоен тем, что этот человек пытается составить список с аналогичной логикой.
Дэйв Лю
0

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

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]
nums = [i for i in nums if i is not None]

это просто заменяет значение на None, если условие не выполняется, а затем переопределяет список без значений None. таким образом они сохраняют свой индекс, если выполняется условие

НЕОН_СОЛИС
источник