Есть ли в Python тернарный условный оператор?

avatar
Devoted
27 декабря 2008 в 08:32
2231314
33
6821

Если в Python нет тернарного условного оператора, можно ли смоделировать его, используя другие языковые конструкции?

Источник
ジョージ
26 мая 2011 в 00:48
4

Хотя Python старше 2.5 медленно уходит в историю, вот список старых уловок с тернарными операторами до 2.5: «Идиомы Python», ищите текст «Условное выражение». Википедия тоже очень полезна Ж :-)

Brent Bradburn
10 января 2013 в 05:57
168

В официальной документации Python 3.0, упомянутой в комментарии выше, это называется «conditional_expressions» и определяется очень загадочно. В этой документации даже нет термина «тройной», поэтому вам будет сложно найти его через Google, если вы точно не знаете, что искать. Документация версии 2 несколько более полезна и включает ссылку на «PEP 308», которая включает много интересного исторического контекста, связанного с этим вопросом.

user313114
15 декабря 2014 в 21:14
33

«троичный» (имеющий три входа) является косвенным свойством этого импелмента, а не определяющим свойством концепции. например: SQL имеет case [...] { when ... then ...} [ else ... ] end для аналогичного эффекта, но совсем не троичный.

user313114
15 декабря 2014 в 21:20
12

также ISO / IEC 9899 (стандарт языка программирования C) раздел 6.5.15 называет его «условным оператором».

HelloGoodbye
9 июня 2016 в 08:11
11

Википедия подробно описывает это в статье «?:».

sdaffa23fdsf
14 марта 2018 в 04:20
1

Он упоминается здесь docs.python.org/3/faq/…, но не упоминается в стандартной библиотеке Python

Scott Martin
15 августа 2018 в 13:25
13

За годы, прошедшие после комментария nobar, документация по условным выражениям была обновлена ​​и теперь содержит Условные выражения (иногда называемые «тернарным оператором») ...

Kaan E.
22 августа 2020 в 02:58
1

Иногда я задаюсь вопросом, как это возможно, что на вопрос «да» или «нет» можно получить 26 ответов

mins
25 октября 2020 в 16:53
1

@KaanE. и, прежде всего, копипаст друг друга с разными комментариями. Итак, значение находится в комментариях ... В любом случае, по состоянию на 2020 год исчерпывающий ответ находится в документации «Тернарные операторы»: « Тернарные операторы более известны как условные выражения [...] они стали частью Python в версии 2.4. "

Ответы (33)

avatar
Vinko Vrsalovic
5 августа 2020 в 23:52
7881

Да, это было добавлено в версии 2.5. Синтаксис выражения:

a if condition else b

Сначала оценивается condition, затем оценивается и возвращается ровно одно из a или b и возвращается на основе логического значения condition. Если condition оценивается как True, то a оценивается и возвращается, но b игнорируется, или иначе, когда b оценивается и возвращается, но a игнорируется. <370526278>

Это позволяет короткое замыкание, потому что, когда condition истинно, оценивается только a, а b не оценивается вообще, но когда condition ложно, оценивается только b, а <370526> не оценивается оценено вообще.

Например:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Обратите внимание, что условные выражения - это выражение , а не выражение . Это означает, что вы не можете использовать операторы присваивания или pass или другие операторы в условном выражении :

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

Однако вы можете использовать условные выражения для присвоения переменной, например:

x = a if True else b

Условное выражение можно рассматривать как переключение между двумя значениями. Это очень полезно, когда вы находитесь в ситуации «того или иного значения», но больше ничего не делает.

Если вам нужно использовать операторы, вы должны использовать обычный if оператор вместо условного выражения .

.

Имейте в виду, что некоторые питонисты осуждают его по нескольким причинам:

  • Порядок аргументов отличается от порядка аргументов классического тернарного оператора condition ? a : b из многих других языков (таких как C, C ++, Go, Perl, Ruby, Java, Javascript и т. Д.), Что может привести к ошибкам когда люди, незнакомые с "неожиданным" поведением Python, используют его (они могут изменить порядок аргументов).
  • Некоторые считают его "громоздким", поскольку он противоречит нормальному ходу мысли (сначала нужно думать о состоянии, а затем о последствиях).
  • Стилистические причины. (Хотя 'inline if' может быть действительно полезным и сделать ваш сценарий более кратким, он действительно усложняет ваш код)

Если у вас проблемы с запоминанием порядка, помните, что при чтении вслух вы (почти) говорите то, что имеете в виду. Например, x = 4 if b > 8 else 9 читается вслух как x will be 4 if b is greater than 8 otherwise 9.

Официальная документация:

yota
25 января 2016 в 15:07
321

Порядок может показаться странным для программистов, однако f(x) = |x| = x if x > 0 else -x звучит очень естественно для математиков. Вы также можете понимать это так же, как и A в большинстве случаев, за исключением случая C, тогда вам следует делать B вместо этого ...

Kal Zekdor
6 марта 2016 в 09:23
146

При использовании будьте осторожны с порядком операций. Например, строка z = 3 + x if x < y else y. Если x=2 и y=1, можно ожидать, что это даст 4, но на самом деле это даст 1. z = 3 + (x if x > y else y) - правильное использование.

Kal Zekdor
15 апреля 2016 в 00:36
14

Дело в том, что если вы хотите выполнить дополнительные оценки после , условное выражение оценивается, например, добавление значения к результату, вам нужно либо добавить дополнительное выражение к обеим сторонам (z = 3 + x if x < y else 3 + y), либо сгруппируйте условное (z = 3 + (x if x < y else y) или z = (x if x < y else y) + 3)

MrGeek
26 мая 2017 в 15:31
1

что, если есть несколько условий?

Dimesio
9 августа 2017 в 06:08
0

@MrGeek, вы можете сгруппировать логические выражения. "foo" if (bool или bool && bool и т. д.) else "bar"

MrGeek
9 августа 2017 в 09:17
0

@Dimesio Я имел в виду что-то вроде if (c1) a1 elif (c2) a2 elif ... else a (n).

Dimesio
11 августа 2017 в 00:04
5

@MrGeek, я понимаю, что вы имеете в виду, так что вы в основном будете вкладывать операции: `" foo "if Bool else (" bar "if Bool else" foobar ")`

Albert van der Horst
17 июня 2018 в 12:50
5

Программистам нужна точная и правильная формулировка даже больше, чем математикам, потому что в математике всегда используются базовые концепции. Убедительным аргументом является оператор%, имитирующий использование слова «mod» в математике, было бы катастрофой. Так что нет, я не принимаю ваш аргумент. Это похоже на соблюдение имперских единиц. Groetjes Albert

BeMyGuestPlease
8 сентября 2019 в 15:02
0

Для выражения: 'x and y' и 'x or y' и их возвращаемых значений я рекомендую проверить docs.python.org/3/reference/expressions.html#boolean-operations, а также другой пост : coderhelper.com/questions/3181901/…

Baldrickk
10 октября 2019 в 13:45
3

@KalZekdor Я прочитал это и ожидал, что 1 ... Мне потребовалось несколько секунд, чтобы понять, как вы должны были это прочитать, чтобы сделать 4 возможными.

QtRoS
30 января 2020 в 11:18
0

Go не имеет тернарного оператора, братан.

Gerard ONeill
9 марта 2020 в 23:35
1

Хорошее объяснение, но короткое замыкание не означает то, что вы думаете - это означает, что остальная часть условия не оценивается, если «истинность» всего условия может быть определена заранее. Утверждение 'b' никогда не оценивается даже в языках без короткого замыкания. Пример: if (arr! = Null && arr [0] = 1) ...

avatar
10 апреля 2022 в 17:39
2

Синтаксис тернарного оператора в Python:

[on_true] if [expression] else [on_false]

Используя этот синтаксис, вот как мы могли бы переписать приведенный выше код, используя тернарный оператор Python:

game_type = 'home'
shirt = 'white' if game_type == 'home' else 'green'

Это все еще довольно ясно, но намного короче. Обратите внимание, что выражение может быть любым типом выражения, включая вызов функции, который возвращает значение, которое оценивается как True или False.

avatar
16 февраля 2022 в 23:09
2

Да, есть, но он отличается от языков программирования, подобных C-синтаксису (то есть condition ? value_if_true : value_if_false

В Python это выглядит так: value_if_true if condition else value_if_false

Пример: even_or_odd = "even" if x % 2 == 0 else "odd"

avatar
DevLoverUmar
6 февраля 2022 в 13:56
1

Версия if else-if может быть записана как:

sample_set="train" if "Train" in full_path else ("test" if "Test" in full_path else "validation")
avatar
6 февраля 2022 в 13:46
0

Есть несколько способов. Самый простой — использовать условие внутри метода print.

.

Вы можете использовать

print("Twenty" if number == 20 else "Not twenty")

Что эквивалентно:

if number == 20:
    print("Twenty")
else:
    print("Not twenty")

Таким образом можно напечатать более двух операторов. Например:

if number == 20:
    print("Twenty")
elif number < 20:
    print("Lesser")
elif 30 > number > 20:
    print("Between")
else:
    print("Greater")

может быть записано как:

print("Twenty" if number == 20 else "Lesser" if number < 20 else "Between" if 30 > number > 20 else "Greater")
avatar
30 декабря 2021 в 14:17
0

Простым, но полезным приемом может быть использование:

foo = "True" and test or "False"
avatar
29 декабря 2021 в 18:53
0

Питонический способ делать вещи:

"true" if var else "false"

Но всегда существует другой способ выполнения троичного условия:

"true" and var or "false"
avatar
23 декабря 2020 в 10:01
13

Ответ Винко Врсаловича достаточно хорош. Осталось только одно:

Обратите внимание, что условные выражения - это выражение , а не инструкция . Это означает, что вы не можете использовать операторы присваивания или pass или другие операторы в условном выражении

Оператор Walrus в Python 3.8

После того, как этот оператор моржа был введен в Python 3.8, кое-что изменилось.

(a := 3) if True else (b := 5)

дает a = 3 и b is not defined,

(a := 3) if False else (b := 5)

дает a is not defined и b = 5 и

c = (a := 3) if False else (b := 5)

дает c = 5, a is not defined и b = 5.

Даже если это может показаться некрасивым, присваивания можно выполнять внутри условных выражений после Python 3.8. В любом случае, в этом случае все же лучше использовать обычный if оператор .

Andrew Anderson
4 августа 2021 в 12:48
0

В первом примере: (a := 3) if True else (b := 5) на самом деле это избыточный первый оператор моржа. Это будет делать: a = 3 if True else (b := 5)

Ddavid
5 августа 2021 в 15:36
0

@AndrewAnderson Нет, это не лишнее. Вам следует сравнить и первый, и второй примеры. Вы можете объединить их и принять во внимание следующее: (a := 3) if x else (b := 5), вы всегда получаете либо a, либо b, но не оба одновременно. Однако рассмотрим a = 3 if x else (b := 5), когда x == False, вы получите a = 5 и b = 5, где оба они назначены.

Andrew Anderson
6 августа 2021 в 11:56
0

Да, это правильно :). Я рассматривал это только для случая x=True, который, конечно, ограничен.

Ddavid
7 августа 2021 в 12:30
0

Поскольку на самом деле мы не записываем этот код if True else, причина первого примера сравнивается только с другими примерами.

avatar
user118967
22 октября 2020 в 14:04
7

Другие ответы правильно говорят о тернарном операторе Python. Я хотел бы дополнить его, упомянув сценарий, для которого часто используется тернарный оператор, но для которого есть лучшая идиома. Это сценарий использования значения по умолчанию.

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

run_algorithm(option_value if option_value is not None else 10)

или, если для option_value никогда не задано ложное значение (0, "" и т. Д.), Просто

run_algorithm(option_value if option_value else 10)

Однако в этом случае лучшим решением будет просто написать

run_algorithm(option_value or 10)
ruancomelli
20 октября 2020 в 15:21
3

Ценное дополнение, но я не согласен: option_value or 10 не лучше, чем option_value if option_value is not None else 10. Он действительно короче, но мне кажется странным и может привести к ошибкам. Что произойдет, если, например, option_value = 0? Первый фрагмент будет запускать run_algorithm(0), потому что option_value не None. Однако второй и третий фрагменты будут запускать run_algorithm(10), потому что 0 является ложным. Эти два фрагмента не эквивалентны, и, следовательно, один не лучше другого. И явное лучше, чем неявное.

user118967
22 октября 2020 в 14:04
0

@ruancomelli: Хорошее замечание. Я изменил ответ, чтобы отразить это исправление.

user118967
22 октября 2020 в 14:06
4

Что касается того, что это выглядело странно, мне интересно, не выглядело ли это странно для вас, потому что вы заметили неточность (что на самом деле это не было эквивалентом). Для меня это звучит естественно, потому что напоминает мою английскую фразу: «Используйте то или иное (если первый вариант недоступен)». Но, конечно, это субъективно. Полезно знать, что это не всем кажется естественным.

ruancomelli
28 октября 2020 в 19:44
2

Намного лучше! И спасибо за объяснение относительно идиомы "или". Мне это кажется странным, потому что я склонен думать о or как о функции, отображающей два аргумента в логическое значение, поэтому я ожидаю, что она вернет либо True, либо False (это происходит во многих других языках программирования). Но «используйте то или иное» - это хорошая мнемоника, которая определенно поможет мне (и, надеюсь, другим) запомнить этот шаблон.

avatar
Natesh bhat
20 июня 2020 в 09:12
22

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

[condition] and [expression_1] or [expression_2] ;

Пример: -

print(number%2 and "odd" or "even")

Будет напечатано «нечетное», если число нечетное, или «четное», если число четное.


Результат: - Если условие истинно, выполняется exp_1, иначе выполняется exp_2.

Примечание: - 0, None, False, emptylist, emptyString оценивается как False. И любые данные, кроме 0, оцениваются как True.

Вот как это работает:

если условие [условие] становится "Истина", тогда выражение_1 будет оцениваться, но не выражение_2. Если мы «и» что-то с 0 (нулем), результат всегда будет быстрым. Итак, в приведенном ниже заявлении:

0 and exp

Выражение exp вообще не будет оцениваться, поскольку "and" с 0 всегда будет оцениваться как ноль, и нет необходимости оценивать выражение. Так работает сам компилятор на всех языках.

В

1 or exp

выражение exp вообще не будет оцениваться, так как «или» с 1 всегда будет 1. Так что вычислять выражение exp не будет, так как результат в любом случае будет 1. (методы оптимизации компилятора).

Но в случае

True and exp1 or exp2

Второе выражение exp2 не будет оцениваться, поскольку True and exp1 будет истинным, если exp1 не ложно.

Аналогично в

False and exp1 or exp2

Выражение exp1 не будет оцениваться, так как False эквивалентно записи 0 и выполнение «and» с 0 будет само по себе 0, но после exp1, поскольку используется «или», оно будет оценивать выражение exp2 после «или».


Примечание: - Этот вид ветвления с использованием «или» и «и» может использоваться только в том случае, если выражение_1 не имеет истинного значения False (или 0, или None, или emptylist [] или emptystring ''.), поскольку если выражение_1 становится ложным, тогда выражение_2 будет оцениваться из-за наличия "или" между exp_1 и exp_2.

Если вы все же хотите, чтобы это работало для всех случаев, независимо от того, какие истинные значения exp_1 и exp_2, сделайте следующее: -

[condition] and ([expression_1] or 1) or [expression_2] ;

moi
20 октября 2017 в 06:37
0

Если вы хотите использовать это в контексте x = [condition] and ([expression_1] or 1) or [expression_2] и expression_1 оценивается как false, x будет 1, а не expression_1. Используйте принятый ответ.

avatar
26 марта 2020 в 21:59
-1

Синтаксис Python по умолчанию val = a if cond else b кажется громоздким, поэтому иногда делаю так:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

Конечно, у него есть обратная сторона - всегда оцениваются обе стороны (a и b), но синтаксис для меня понятнее

eatsfood
28 апреля 2020 в 16:57
3

Это кажется вдвое большим объемом работы, большим использованием ОЗУ и более запутанным, чем более простой оператор val = a if cond else b.

Rainer Koirikivi
11 января 2021 в 13:22
0

Также здесь каждый раз оцениваются как a, так и b, в отличие от a if cond else b

avatar
Todd
15 марта 2020 в 06:42
6

Python имеет троичную форму для присвоений; однако может существовать даже более короткая форма, о которой люди должны знать.

Очень часто требуется присвоить переменной то или иное значение в зависимости от условия.

>>> li1 = None
>>> li2 = [1, 2, 3]
>>> 
>>> if li1:
...     a = li1
... else:
...     a = li2
...     
>>> a
[1, 2, 3]

^ Это полная форма для выполнения таких заданий.

Ниже представлена ​​троичная форма. Но это не самый лаконичный способ - см. Последний пример.

>>> a = li1 if li1 else li2
>>> 
>>> a
[1, 2, 3]
>>> 

В Python вы можете просто использовать or для альтернативных назначений.

>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Вышеупомянутое работает, так как li1 равно None, и интерпритация обрабатывает это как False в логических выражениях. Затем interp переходит и оценивает второе выражение, которое не является None и не является пустым списком, поэтому ему присваивается значение.

Это также работает с пустыми списками. Например, если вы хотите назначить a любому списку, в котором есть элементы.

>>> li1 = []
>>> li2 = [1, 2, 3]
>>> 
>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Зная это, вы можете выполнять такие задания всякий раз, когда с ними сталкиваетесь. Это также работает со строками и другими итерациями. Вы можете назначить a в зависимости от того, какая строка не пуста.

>>> s1 = ''
>>> s2 = 'hello world'
>>> 
>>> a = s1 or s2
>>> 
>>> a
'hello world'
>>> 

Мне всегда нравился тернарный синтаксис C, но Python идет дальше!

Я понимаю, что некоторые могут сказать, что это не лучший стилистический выбор, потому что он основан на механике, которая не сразу очевидна для всех разработчиков. Я лично не согласен с этой точкой зрения. Python - это язык с богатым синтаксисом и множеством идиоматических уловок, которые не сразу бросаются в глаза даблеру. Но чем больше вы изучаете и понимаете механизмы лежащей в основе системы, тем больше вы это цените.

avatar
Walter Tross
22 февраля 2020 в 13:03
26

Одна из альтернатив Python условному выражению

"yes" if boolean else "no"

следующий:

{True:"yes", False:"no"}[boolean]

со следующим красивым расширением:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

Остается самая короткая альтернатива:

("no", "yes")[boolean]

, но альтернативы

нет
yes() if boolean else no()

, если вы хотите избежать оценки yes() и no(), потому что в

(no(), yes())[boolean]  # bad

оцениваются как no(), так и yes().

avatar
23 октября 2019 в 07:22
-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

он может быть вложен по вашему желанию. удачи

**

avatar
16 октября 2019 в 08:37
14

Как уже было сказано, да, в python есть тернарный оператор:

<expression 1> if <condition> else <expression 2>

Дополнительная информация:

Если <expression 1> является условием, вы можете использовать оценку короткого замыкания:

a = True
b = False

# Instead of this:
x = a if a else b

# You could use Short-cirquit evaluation:
x = a or b

PS: Конечно, оценка короткого замыкания не является тернарным оператором, но часто тернарный метод используется в тех случаях, когда короткого замыкания будет достаточно.

avatar
Simon Zimmermann
15 мая 2019 в 15:03
304

<expression 1> if <condition> else <expression 2>

a = 1
b = 2

1 if a > b else -1 
# Output is -1

1 if a > b else -1 if a < b else 0
# Output is -1
Roy Tinker
4 октября 2010 в 21:14
88

Это подчеркивает основное предназначение тернарного оператора: выбор значения. Это также показывает, что более одного тернара можно объединить в одно выражение.

Jon Coombs
1 декабря 2014 в 21:30
6

@Craig, я согласен, но также полезно знать, что произойдет, если нет скобок. В реальном коде я бы тоже стал вставлять явные скобки.

mins
25 октября 2020 в 16:41
0

Использование: return 3 if t > 10 else t/2

avatar
12 мая 2019 в 13:03
-1

Удобный способ объединения нескольких операторов в цепочку:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

avatar
gorsky
9 мая 2019 в 09:45
106

К сожалению,

(falseValue, trueValue)[test]

решение не имеет поведения при коротком замыкании; таким образом, как falseValue, так и trueValue оцениваются независимо от условия. Это могло быть неоптимальным или даже ошибочным (т.е. оба trueValue и falseValue могли быть методами и иметь побочные эффекты).

Одно из решений этой проблемы:

(lambda: falseValue, lambda: trueValue)[test]()

(выполнение отложено до тех пор, пока не станет известен победитель;)), но это вносит несогласованность между вызываемыми и не вызываемыми объектами. Кроме того, это не решает случай использования свойств.

Итак, история гласит - выбор между 3 упомянутыми решениями - это компромисс между наличием функции короткого замыкания, использованием по крайней мере ython 2.5 (IMHO, больше не проблема) и отсутствием склонности к "trueValue -оценкам -to-false "ошибки.

Perkins
11 октября 2018 в 17:34
3

Хотя трюк с кортежами лямбда-выражений работает, он занимает примерно в 3 раза больше времени, чем тернарный оператор. Это будет разумной идеей, если она сможет заменить длинную цепочку if else if.

avatar
Simplans
26 января 2019 в 14:05
85

Тернарный оператор на разных языках программирования

Здесь я просто пытаюсь показать некоторые важные различия в ternary operator между двумя языками программирования.

Тернарный оператор в Javascript

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0

Тернарный оператор в Ruby

a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0

Тернарный оператор в Scala

val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0

Тернарный оператор в программировании на R

a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0

Тернарный оператор в Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
fralau
10 января 2018 в 17:12
7

Это может показаться самоуверенным; но, по сути, он говорит о том, что синтаксис Python, вероятно, будет понят человеком, который никогда не видел тернарного оператора, в то время как очень немногие люди поймут более обычный синтаксис, если им сначала не скажут, что он означает.

Albert van der Horst
17 июня 2018 в 12:55
2

Algol68: a = .if. .истинный. .потом. 1 .else. 0 .fi. Это также может быть выражено a = (. True. | 1 | 0). Как обычно, Algol68 является улучшением по сравнению с его преемниками.

Varun Garg
5 ноября 2020 в 08:44
0

что-то простое, как print a || '<alt text>' в рубине - это пита в питоне print a if a is not None else 'alt text'

lenz
15 ноября 2020 в 20:24
1

@VarunGarg Но, конечно, вы можете сказать print(a or 'alt text') на Python.

avatar
ARGeo
4 января 2019 в 22:02
11

Многие языки программирования, производные от C, обычно имеют следующий синтаксис тернарного условного оператора:

<condition> ? <expression1> : <expression2>

Сначала Python B enevolent D ictator F или <3099634> конечно) отклонил его (как непитонический стиль), поскольку его довольно сложно понять людям, не привыкшим к C языку. Кроме того, знак двоеточия : уже имеет множество применений в Python. После того, как PEP 308 был одобрен, Python наконец получил собственное сокращенное условное выражение (то, что мы используем сейчас):

<expression1> if <condition> else <expression2>

Итак, сначала он оценивает условие. Если он возвращает True, выражение1 будет оценено для получения результата, в противном случае будет оценено выражение2 . Из-за механики отложенной оценки - будет выполнено только одно выражение.

Вот несколько примеров (условия будут оцениваться слева направо):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

Тернарные операторы могут быть соединены последовательно:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

Следующий такой же, как и предыдущий:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

Надеюсь, это поможет.

avatar
6 декабря 2018 в 14:45
26
a if condition else b

Просто запомните эту пирамиду, если у вас возникли проблемы с запоминанием:

     condition
  if           else
a                   b 
avatar
PythonLover
21 октября 2018 в 20:46
10

ДА, у python есть тернарный оператор, вот синтаксис и пример кода, чтобы продемонстрировать то же самое :)

#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false


a= input("Enter the First Number ")
b= input("Enter the Second Number ")

print("A is Bigger") if a>b else print("B is Bigger")
realmanusharma
21 октября 2018 в 20:45
0

Я добавил пример однострочного оператора, чтобы проверить, какое число велико, чтобы проработать его дальше.

Thierry Lathuille
21 октября 2018 в 21:52
1

print действительно не лучший выбор, так как это приведет к ошибке SyntaxError в Python2.

realmanusharma
21 октября 2018 в 21:54
0

@Thierry Lathuille здесь я использовал функцию print (), а не оператор печати, функция печати предназначена для Python 3, а оператор печати - для Python 2

Thierry Lathuille
21 октября 2018 в 21:58
0

Вопрос уже был задан по SO, просто попробуйте с Python 2, и вы убедитесь в этом сами. 'print (' hello ') - это совершенно допустимый синтаксис в Python 2.7, но способ его анализа заставляет ваш код выше генерировать SyntaxError.

avatar
ewwink
26 апреля 2018 в 16:22
-3

если переменная определена и вы хотите проверить, имеет ли она значение, вы можете просто a or b

def test(myvar=None):
    # shorter than: print myvar if myvar else "no Input"
    print myvar or "no Input"

test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)

выведет

no Input
no Input
no Input
hello
['Hello']
True
Perkins
11 октября 2018 в 17:13
1

Хотя это полезно для подобных задач, это не тернарное условие. Он работает для замены x if x else y, но не x if z else y.

avatar
4 апреля 2018 в 14:02
24

Тернарный условный оператор просто позволяет тестировать условие в одной строке, заменяя многострочное if-else, делая код компактным.

Синтаксис:

[on_true] if [выражение] else [on_false]

1- Простой метод использования тернарного оператора:

# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min)  # Output: 10

2- Прямой метод использования кортежей, словаря и лямбда:

# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda  we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- Тернарный оператор может быть записан как вложенный if-else:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
        if a > b else "b is greater than a")

Вышеупомянутый подход можно записать как:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
    if a > b:
        print("a is greater than b")
    else:
        print("b is greater than a")
else:
    print("Both a and b are equal") 
# Output: b is greater than a
Perkins
11 октября 2018 в 17:28
1

Обратите внимание, что тернарный оператор меньше (в памяти) и быстрее, чем вложенный if. Кроме того, ваш вложенный if-else на самом деле не является переписыванием тернарного оператора и будет производить другой вывод для выбранных значений a и b (особенно, если один из типов реализует странный метод __ne__).

avatar
kenorb
7 августа 2017 в 14:22
139

Оператор условного выражения в Python был добавлен в 2006 году как часть предложения по усовершенствованию Python 308. Его форма отличается от обычного оператора ?: и выглядит так:

<expression1> if <condition> else <expression2>

, что эквивалентно:

if <condition>: <expression1> else: <expression2>

Вот пример:

result = x if a > b else y

Другой синтаксис, который можно использовать (совместим с версиями до 2.5):

result = (lambda:y, lambda:x)[a > b]()

где операнды лениво вычисляются.

Другой способ - индексировать кортеж (что не согласуется с условным оператором большинства других языков):

result = (y, x)[a > b]

или явно созданный словарь:

result = {True: x, False: y}[a > b]

Другой (менее надежный), но более простой способ - использовать операторы and и or:

result = (a > b) and x or y

однако это не сработает, если x будет False.

Возможный обходной путь - создать списки или кортежи x и y, как показано ниже:

result = ((a > b) and [x] or [y])[0]

или:

result = ((a > b) and (x,) or (y,))[0]

Если вы работаете со словарями, вместо использования тернарного условного выражения вы можете воспользоваться get(key, default), например:

shell = os.environ.get('SHELL', "/bin/sh")

Источник: ?: В Python в Википедии

Walter Tross
9 февраля 2019 в 18:07
1

result = {1: x, 0: y}[a > b] - еще один возможный вариант (True и False на самом деле целые числа со значениями 1 и 0)

avatar
Aaron Hall
8 августа 2016 в 18:56
44

Есть ли в Python тернарный условный оператор?

Да. Из файла грамматики :

test: or_test ['if' or_test 'else' test] | lambdef

Интересующая часть:

or_test ['if' or_test 'else' test]

Итак, тернарная условная операция имеет вид:

expression1 if expression2 else expression3

expression3 будет вычисляться лениво (то есть оцениваться, только если expression2 ложно в логическом контексте). А из-за рекурсивного определения вы можете связывать их бесконечно долго (хотя это может считаться плохим стилем).

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Примечание по использованию:

Обратите внимание, что за каждым if должен следовать else. Людям, изучающим понимание списков и выражения генератора, может быть сложно усвоить этот урок - следующее не сработает, поскольку Python ожидает третьего выражения для else:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

, что вызывает SyntaxError: invalid syntax. Таким образом, приведенное выше является либо неполным фрагментом логики (возможно, пользователь ожидает отсутствия операции в ложном условии), либо может быть предназначено использовать выражение2 в качестве фильтра - отмечает, что следующее является допустимым Python:

[expression1 for element in iterable if expression2]

expression2 работает как фильтр для понимания списка и не является тернарным условным оператором.

Альтернативный синтаксис для более узкого регистра:

Вам может показаться несколько неприятным писать следующее:

expression1 if expression1 else expression2

expression1 необходимо будет дважды оценить с использованием вышеупомянутого использования. Это может ограничить избыточность, если это просто локальная переменная. Однако распространенная и эффективная идиома Pythonic для этого варианта использования - использовать сокращенное поведение or:

expression1 or expression2

, что эквивалентно по семантике. Обратите внимание, что некоторые руководства по стилям могут ограничивать это использование по причинам ясности - они действительно содержат много смысла в очень небольшом синтаксисе.

JSDBroughton
18 февраля 2016 в 13:05
1

expression1 or expression2 аналогичен и имеет те же недостатки / плюсы, что и expression1 || expression2 в javascript

Aaron Hall♦
27 мая 2016 в 04:37
1

Спасибо, @selurvedu - это может сбивать с толку, пока вы не разберетесь. Я научился на собственном горьком опыте, так что твой путь может быть не таким трудным. ;) Использование if без else в конце выражения генератора или понимания списка отфильтрует итерацию. Спереди это тернарная условная операция, требующая else. Ваше здоровье!!

tchrist
26 января 2019 в 14:12
0

@AaronHall Несмотря на то, что вы используете метасинтаксический expressionN для всех экземпляров единообразно, его легче понять с помощью именования, которое отличает условное тестовое выражение от двух результирующих выражений; например, result1 if condition else result2. Это особенно очевидно при вложении (или цепочке): result1 if condition1 else result2 if condition2 else result3. Видите, насколько лучше это читается?

Aaron Hall♦
26 января 2019 в 18:24
0

@tchrist благодарит за обзор - если вы посмотрите историю изменений, то в данный момент у этого поста две редакции. Большинство других моих ответов, особенно самых популярных, пересматривались снова и снова. Этот ответ никогда не привлекает моего внимания, потому что статус вики сообщества не дает мне права на содержание, и поэтому я никогда не вижу никаких голосов по нему. Поскольку сейчас у меня нет времени редактировать это, лягушка знает, когда это снова привлечет мое внимание в будущем. Я вижу, что вы отредактировали главный ответ, поэтому не стесняйтесь заимствовать / цитировать мой материал из этого сообщения в этом (и цитируйте меня, если кстати!)

avatar
Todor
23 мая 2016 в 19:16
21

Скорее подсказка, чем ответ (не нужно повторять очевидное сотню раз), но я иногда использую его как ярлык для одной строки в таких конструкциях:

if conditionX:
    print('yes')
else:
    print('nah')

становится:

print('yes') if conditionX else print('nah')

Некоторые (многие :) могут осудить это как непифоническое (даже рубиновое :), но я лично считаю его более естественным - то есть, как вы бы выразили это обычно, плюс немного более визуально привлекательным в больших блоках код.

frederick99
20 августа 2017 в 06:07
7

Я предпочитаю print( 'yes' if conditionX else 'nah' ) вашему ответу. :-)

Todor Minakov
26 октября 2017 в 11:40
0

То есть, если вы хотите print() в обоих случаях - и это выглядит немного более питоническим, я должен признать :) Но что, если выражения / функции не совпадают - например, print('yes') if conditionX else True - чтобы получить print() только в правде conditionX

Thierry Lathuille
21 октября 2018 в 21:51
0

Чтобы добавить к замечанию Фредерика99, еще одна причина, по которой следует избегать print('yes') if conditionX else print('nah'), заключается в том, что он дает SyntaxError в Python2.

Todor Minakov
22 октября 2018 в 04:09
0

Единственная причина, по которой он дает синтаксическую ошибку, заключается в том, что в Python 2 print является оператором - print "yes", а в Python 3 это функция - print("yes"). Это можно решить, используя его как выражение, или лучше - from future import print_function.

avatar
17 октября 2015 в 07:43
178

Из документация:

Условные выражения (иногда называемые «тернарным оператором») имеют самый низкий приоритет среди всех операций Python.

Выражение x if C else y сначала оценивает условие, C ( не x ); если C истинно, вычисляется x и возвращается его значение; в противном случае вычисляется y и возвращается его значение.

См. PEP 308 для получения дополнительных сведений об условных выражениях.

Новое, начиная с версии 2.5.

avatar
17 октября 2015 в 07:35
886

Вы можете индексировать кортеж:

(falseValue, trueValue)[test]

test необходимо вернуть Истина или Ложь .
Может быть безопаснее всегда реализовывать его как:

(falseValue, trueValue)[test == True]

или вы можете использовать встроенный bool(), чтобы обеспечить логическое значение:

(falseValue, trueValue)[bool(<expression>)]
SilverbackNet
4 февраля 2011 в 02:25
658

Обратите внимание, что эта всегда оценивает все, тогда как конструкция if / else оценивает только выигрышное выражение.

Dustin Getz
8 марта 2012 в 19:31
134

(lambda: print("a"), lambda: print("b"))[test==true]()

martineau
31 мая 2012 в 18:20
19

Следует отметить, что содержимое [] может быть произвольным выражением. Кроме того, в целях безопасности вы можете явно проверить правдивость, написав [bool(<expression>)]. Функция bool() существует с версии 2.2.1.

jon skulski
28 мая 2015 в 20:57
2

Это идиоматика в питоне? Кажется сбивающим с толку, но, возможно, это соглашение

Dr. Andrew
19 февраля 2016 в 07:49
0

Уродливое в глазах смотрящего, и я вовсе не считаю это уродливым. Он лаконично использует тот факт, что bool является подклассом int и что индексы Python основаны на 0. По общему признанию, это, вероятно, не самый эффективный (как упоминал @SilverBackNet, оба варианта оценены). Однако это отлично работает для выбора между 1 из 2 строк, как сказал @Claudiu - я использую его для этого все время. Например: '%d item%s to process!'%(num_items,('','s')[num_items > 1]) или 'Null hypothesis %s be rejected (p-val = %0.4f)'%(("can't",'must')[pval<alpha],pval).

JDM
1 марта 2016 в 18:43
12

Я проделал аналогичный трюк - только один или два раза, но сделал это - путем индексации в словарь с ключами True и False: {True:trueValue, False:falseValue}[test] Я не знаю, менее эффективно ли это , но он, по крайней мере, избегает споров между «элегантным» и «уродливым». Нет никакой двусмысленности в том, что вы имеете дело с логическим значением, а не с int.

Breezer
29 ноября 2017 в 13:59
3

Этот трюк может помочь избежать атак на алгоритмы, основанных на времени, если он всегда оценивает оба возможных результата и избегает пропуска кода («если» пропускается).

Baldrickk
10 октября 2019 в 13:48
0

@jskulski только в старом питоне, до 2.5. Даже тогда if cond: [expression_1] else: [expression_2] был более распространенным

problemofficer
23 сентября 2020 в 10:16
3

Без сомнения, это «крутая» и интересная идея. Но реальный код должен быть легко читаемым и наименее подверженным ошибкам. Если бы один из моих разработчиков использовал это, я бы попросил его изменить это. Поскольку IMHO это не должно использоваться в производственном коде, я проголосовал за ответ.

Mark Ransom
19 октября 2020 в 22:02
1

@JDM нет двусмысленности, поскольку bool на самом деле является подклассом int. И я бы сказал, что этот ответ и ваш вариант и уродливы.

JDM
23 февраля 2021 в 13:40
0

@MarkRansom, нет аргументов в пользу того, что оба являются некрасивыми (и больше не нужны) обходными путями. Однако в ответе есть проблема с садовой дорожкой, которую я избегаю. Поместите индекс кортежа перед большинством, и я гарантирую, что они , а не сразу подумают: «О, эта переменная должна представлять истинное / ложное значение». Они начнут с предположения, что это порядковый номер, и только после того, как ломают голову над контекстом, поймут его истинное предназначение. Это двусмысленность, о которой я говорю.

avatar
13 января 2014 в 07:16
384

Для версий до 2.5 есть трюк:

[expression] and [on_true] or [on_false]

Он может дать неверные результаты, если on_true имеет ложное логическое значение. 1
Хотя у него есть преимущество оценки выражений слева направо, что, на мой взгляд, яснее.

1. Есть ли эквивалент тернарного оператора C?: "?

ThomasH
21 октября 2009 в 15:33
73

Чтобы избежать этой ловушки, используйте (test и [true_value] или [false_value]) [0].

volcano
13 января 2014 в 07:52
7

Тернарный оператор обычно выполняется быстрее (иногда на 10-25%).

OrangeTux
5 августа 2014 в 12:30
7

@volcano У вас есть источник для меня?

mbomb007
19 марта 2018 в 20:59
5

@OrangeTux Вот дизассемблированный код. Использование метода, предложенного ThomasH, будет еще медленнее.

avatar
20 ноября 2013 в 10:44
26

Имитация тернарного оператора Python.

Например,

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

вывод:

'b greater than a'
Grijesh Chauhan
27 декабря 2013 в 05:50
1

Почему не просто result = (y, x)[a < b] Почему вы используете lambda функцию ?

glglgl
13 февраля 2014 в 08:14
6

@GrijeshChauhan Потому что в "комплиментарных" выражениях e. г. включая вызов функции и т. д., это будет выполнено в обоих случаях. Это могло быть нежелательно.

jocerfranquiz
14 декабря 2020 в 04:29
1

Использование функций lambda является излишним для этого вопроса

SneezeFor16Min
19 января 2021 в 10:11
0

@GrijeshChauhan Короче говоря, это реализует так называемую « оценку короткого замыкания ». Как правило, P ? x : y или x if P else y можно записать как (lambda:y, lambda:x)[P](), но я сомневаюсь, что он имеет лучшую производительность и, следовательно, его необходимость.

avatar
14 января 2013 в 15:56
49

Вы можете часто встретить

cond and on_true or on_false

но это приводит к проблеме, когда on_true == 0

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

там, где вы ожидаете от обычного тернарного оператора этот результат

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
avatar
25 апреля 2012 в 12:02
70

Для Python 2.5 и новее существует особый синтаксис:

[on_true] if [cond] else [on_false]

В старых версиях Pythons тернарный оператор не реализован, но его можно смоделировать.

cond and on_true or on_false

Однако существует потенциальная проблема, которая, если cond оценивается как True, а on_true оценивается как False, то вместо on_true возвращается on_false. Если вам нужно такое поведение, метод в порядке, в противном случае используйте следующее:

{True: on_true, False: on_false}[cond is True] # is True, not == True

, который можно обернуть:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

и используется так:

q(cond, on_true, on_false)

Он совместим со всеми версиями Python.

user3317
26 сентября 2012 в 09:09
2

Поведение не идентично - q("blob", on_true, on_false) возвращает on_false, тогда как on_true if cond else on_false возвращает on_true. Обходной путь - заменить cond на cond is not None в этих случаях, хотя это не идеальное решение.

Jonas Kölker
11 ноября 2013 в 16:11
5

Почему не bool(cond) вместо cond is True? Первый проверяет истинность cond, второй проверяет равенство указателя с объектом True. Как подчеркнуто @AndrewCecil, "blob" правдиво, но это is not True.

Arseny
24 февраля 2014 в 11:51
0

Вау, это выглядит действительно хакерским! :) Технически можно даже написать [on_false, on_True][cond is True], чтобы выражение стало короче.

Hucker
28 марта 2019 в 14:08
0

В этом ответе нет короткого замыкания. Если вызов on_true и on_false обходится дорого, это плохой ответ.