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

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


person Community    schedule 27.12.2008    source источник
comment
Хотя Pythons старше 2.5 медленно уходят в историю, вот список старых уловок тернарных операторов до 2.5: Идиомы Python, найдите текст "Условное выражение". Википедия тоже очень полезна Ж :-)   -  person ジョージ    schedule 26.05.2011
comment
В официальной документации Python 3.0, упомянутой в комментарии выше, это называется conditional_expressions и определяется очень загадочно. В этой документации даже нет термина «троичный», поэтому вам будет сложно найти его через Google, если вы точно не знаете, что искать. Более полезна документация по версии 2, содержащая ссылку на PEP 308, который включает много интересного исторического контекста, связанного с этим вопрос.   -  person Brent Bradburn    schedule 10.01.2013
comment
троичный (имеющий три входа) является косвенным свойством этого импелментации, а не определяющим свойством концепции. например: SQL имеет case [...] { when ... then ...} [ else ... ] end для аналогичного эффекта, но совсем не троичный.   -  person user313114    schedule 16.12.2014
comment
также ISO / IEC 9899 (стандарт языка программирования C) раздел 6.5.15 называет его условным оператором.   -  person user313114    schedule 16.12.2014
comment
Википедия подробно рассматривает этот вопрос в статье ?:.   -  person HelloGoodbye    schedule 09.06.2016
comment
Здесь упоминается docs.python.org/3/faq/, но не упомянут в стандартной библиотеке Python   -  person sdaffa23fdsf    schedule 14.03.2018
comment
За годы, прошедшие после комментария nobar, документация по условным выражениям была обновлено: Условные выражения (иногда называемые «тернарным оператором») ...   -  person Scott Martin    schedule 15.08.2018
comment
Иногда я задаюсь вопросом, как это возможно, что на вопрос «да» или «нет» можно получить 26 ответов   -  person Kaan E.    schedule 22.08.2020
comment
@KaanE. и, прежде всего, копипаст друг друга с разными комментариями. Итак, значение находится в комментариях ... В любом случае, с 2020 года исчерпывающий ответ находится в Документация «Тернарные операторы»: Тернарные операторы более известны как условные выражения [...] они стали частью Python в версии 2.4.   -  person mins    schedule 25.10.2020


Ответы (27)


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

a if condition else b

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

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

Например:

>>> '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.

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

person Community    schedule 27.12.2008
comment
Порядок может показаться странным для программистов, однако f(x) = |x| = x if x > 0 else -x звучит очень естественно для математиков. Вы также можете понимать это так же, как и A в большинстве случаев, за исключением случая C, тогда вам следует делать B вместо этого ... - person yota; 25.01.2016
comment
При использовании будьте осторожны с порядком операций. Например, строка z = 3 + x if x < y else y. Если x=2 и y=1, можно ожидать, что это даст 4, но на самом деле это даст 1. z = 3 + (x if x > y else y) - правильное использование. - person Kal Zekdor; 06.03.2016
comment
Дело в том, что если вы хотите выполнить дополнительные оценки после оценки условия, например, добавление значения к результату, вам нужно либо добавить дополнительное выражение к обеим сторонам (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) - person Kal Zekdor; 15.04.2016
comment
что, если есть несколько условий? - person MrGeek; 26.05.2017
comment
@MrGeek, вы можете сгруппировать логические выражения. foo if (bool или bool && bool и т. д.) else bar - person Dimesio; 09.08.2017
comment
@Dimesio Я имел в виду что-то вроде if (c1) a1 elif (c2) a2 elif ... else a (n). - person MrGeek; 09.08.2017
comment
@MrGeek, я понимаю, что вы имеете в виду, поэтому вы в основном будете вкладывать операции: `foo if Bool else (bar if Bool else foobar)` - person Dimesio; 11.08.2017
comment
Программистам нужна точная и правильная формулировка даже больше, чем математикам, потому что в математике всегда используются базовые концепции. Убедительным аргументом является оператор%, имитирующий способ, которым мод используется в математике, был бы катастрофой. Так что нет, я не принимаю ваш аргумент. Это похоже на соблюдение имперских единиц. Groetjes Albert - person Albert van der Horst; 17.06.2018
comment
Для выражения: 'x and y' и 'x or y' и их возвращаемых значений я рекомендую проверить docs.python.org/3/reference/expressions.html#boolean-operations, а также другой пост: stackoverflow.com/questions/3181901/ - person BeMyGuestPlease; 08.09.2019
comment
@KalZekdor Я прочитал это и ожидал, что 1 ... Мне потребовалось несколько секунд, чтобы понять, как вы должны были это прочитать, чтобы сделать 4 возможными. - person Baldrickk; 10.10.2019
comment
В Go нет тернарного оператора, братан. - person QtRoS; 30.01.2020
comment
Хорошее объяснение, но короткое замыкание не означает то, что вы думаете, это означает, что остальная часть условия не оценивается, если «истинность» всего условия может быть определена заранее. Утверждение 'b' никогда не оценивается даже в языках без короткого замыкания. Пример: if (arr! = Null && arr [0] = 1) ... - person Gerard ONeill; 10.03.2020

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

(falseValue, trueValue)[test]

test должен возвращать True или False.
Возможно, безопаснее всегда реализовывать его как:

(falseValue, trueValue)[test == True]

или вы можете использовать встроенный bool() для обеспечить значение Boolean:

(falseValue, trueValue)[bool(<expression>)]
person Community    schedule 22.01.2009
comment
Обратите внимание, что эта всегда оценивает все, тогда как конструкция if / else оценивает только выигрышное выражение. - person SilverbackNet; 04.02.2011
comment
Следует отметить, что содержимое []s может быть произвольным выражением. Кроме того, в целях безопасности вы можете явно проверить правдивость, написав [bool(<expression>)]. Функция bool() существует с версии 2.2.1. - person martineau; 31.05.2012
comment
Это идиоматика в питоне? Кажется сбивающим с толку, но, возможно, это соглашение - person jon skulski; 28.05.2015
comment
Уродливость в глазах смотрящего, и я вовсе не считаю это уродливым. Он лаконично использует тот факт, что 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). - person Dr. Andrew; 19.02.2016
comment
Я проделал похожий трюк - только один или два раза, но сделал это - путем индексации в словарь с True и False в качестве ключей: {True:trueValue, False:falseValue}[test] Я не знаю, менее эффективно ли это, но, по крайней мере, Избегайте споров между элегантным и уродливым. Нет никакой двусмысленности в том, что вы имеете дело с логическим значением, а не с int. - person JDM; 01.03.2016
comment
Этот трюк может помочь избежать атак на алгоритмы, основанных на времени, если он всегда оценивает оба возможных результата и избегает пропуска кода («если» пропускается). - person Breezer; 29.11.2017
comment
@jskulski только в старом питоне, до 2.5. Но даже тогда if cond: [expression_1] else: [expression_2] был более распространен - person Baldrickk; 10.10.2019
comment
Без сомнения, это крутая и интересная идея. Но реальный код должен быть легко читаемым и наименее подверженным ошибкам. Если бы один из моих разработчиков использовал это, я бы попросил его изменить это. Поскольку IMHO это не должно использоваться в производственном коде, я проголосовал за ответ. - person problemofficer; 23.09.2020
comment
@JDM нет двусмысленности, поскольку bool на самом деле является подклассом int. И я бы сказал, что этот ответ и ваш вариант оба уродливы. - person Mark Ransom; 20.10.2020
comment
@MarkRansom, нет аргументов в пользу того, что оба являются некрасивыми (и больше не нужны) обходными путями. Однако в ответе есть проблема с садовой дорожкой, которую я избегаю. Поместите индекс кортежа перед большинством, и я гарантирую, что они не сразу подумают, о, эта переменная должна представлять истинное / ложное значение. Они начнут с предположения, что это порядковый номер, и только после того, как ломают голову над контекстом, поймут его истинное предназначение. Это двусмысленность, о которой я говорю. - person JDM; 23.02.2021

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

[expression] and [on_true] or [on_false]

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

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

person Community    schedule 27.12.2008
comment
Чтобы избежать этой ловушки, используйте (test и [true_value] или [false_value]) [0]. - person ThomasH; 21.10.2009
comment
Тернарный оператор обычно выполняется быстрее (иногда на 10-25%). - person volcano; 13.01.2014
comment
@volcano У вас есть источник для меня? - person OrangeTux; 05.08.2014
comment
@OrangeTux Вот разобранном код. Использование метода, предложенного ThomasH, будет еще медленнее. - person mbomb007; 19.03.2018

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

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

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

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

Новое с версии 2.5.

person Community    schedule 27.12.2008

Оператор условного выражения в 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]

or:

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

Если вы работаете со словарями, вместо тернарного условного выражения вы можете воспользоваться _ 17_, например:

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

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

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

К сожалению,

(falseValue, trueValue)[test]

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

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

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

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

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

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

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

Здесь я просто пытаюсь показать некоторые важные различия 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
person Community    schedule 21.08.2016
comment
Это может показаться самоуверенным; но, по сути, он говорит о том, что синтаксис Python, вероятно, будет понят человеком, который никогда не видел тернарного оператора, в то время как очень немногие люди поймут более обычный синтаксис, если им сначала не скажут, что он означает. - person fralau; 10.01.2018
comment
Algol68: a = .if. .правда. .тогда. 1 .else. 0 .fi. Это также может быть выражено как a = (. True. | 1 | 0). Как обычно, Algol68 является усовершенствованием своих последователей. - person Albert van der Horst; 17.06.2018
comment
что-то простое, как print a || '<alt text>' в рубине, это лаваш в питоне print a if a is not None else 'alt text' - person Varun Garg; 05.11.2020
comment
@VarunGarg Но, конечно, вы можете сказать print(a or 'alt text') на Python. - person lenz; 15.11.2020

Для 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.

person Community    schedule 25.04.2012
comment
Поведение не идентично - q("blob", on_true, on_false) возвращает on_false, тогда как on_true if cond else on_false возвращает on_true. В таких случаях можно заменить cond на cond is not None, хотя это не идеальное решение. - person ; 26.09.2012
comment
Почему не bool(cond) вместо cond is True? Первый проверяет истинность cond, второй проверяет равенство указателя с объектом True. Как подчеркнул @AndrewCecil, "blob" правда, но is not True. - person Jonas Kölker; 11.11.2013
comment
Вау, это выглядит действительно хакерским! :) Технически можно даже написать [on_false, on_True][cond is True], чтобы выражение стало короче. - person Arseny; 24.02.2014
comment
В этом ответе нет короткого замыкания. Если вызов on_true и on_false обходится дорого, это плохой ответ. - person Hucker; 28.03.2019

Вы часто можете найти

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
person Community    schedule 14.01.2013

Есть ли в 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

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

person Community    schedule 17.11.2015
comment
expression1 or expression2 аналогичен и имеет те же недостатки / достоинства, что и expression1 || expression2 в javascript - person JSDBroughton; 18.02.2016
comment
Спасибо, @selurvedu - это может сбивать с толку, пока вы не разберетесь. Я научился на собственном горьком опыте, так что твой путь может быть не таким трудным. ;) Использование if без else в конце выражения генератора или понимания списка отфильтрует итерацию. Спереди это тернарная условная операция, требующая else. Ваше здоровье!! - person Aaron Hall; 27.05.2016
comment
@AaronHall Несмотря на то, что вы используете метасинтаксический expressionN для всех экземпляров согласованно, это может быть легче понять с помощью именования, которое отличает условное тестовое выражение от двух результирующих выражений; например, result1 if condition else result2. Это особенно очевидно при вложении (или цепочке): result1 if condition1 else result2 if condition2 else result3. Видите, насколько лучше это читается? - person tchrist; 26.01.2019
comment
@tchrist благодарит за обзор - если вы посмотрите историю изменений, то в данный момент у этого поста две редакции. Большинство других моих ответов, особенно самых популярных, пересматривались снова и снова. Этот ответ никогда не привлекает моего внимания, потому что статус вики сообщества не дает мне права на контент, и поэтому я никогда не вижу никаких голосов по нему. Поскольку сейчас у меня нет времени редактировать это, лягушка знает, когда это снова привлечет мое внимание в будущем. Я вижу, что вы отредактировали главный ответ, поэтому не стесняйтесь заимствовать / цитировать мой материал из этого сообщения в этом (и цитируйте меня, если кстати!) - person Aaron Hall; 26.01.2019

Имитация тернарного оператора 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'
person Community    schedule 20.11.2013
comment
Почему не просто result = (y, x)[a < b] Почему вы используете lambda функцию ? - person Grijesh Chauhan; 27.12.2013
comment
@GrijeshChauhan Потому что в сложных выражениях e. грамм. включая вызов функции и т. д., это будет выполнено в обоих случаях. Это могло быть нежелательно. - person glglgl; 13.02.2014
comment
Использование lambda функций является излишним для этого вопроса - person jocerfranquiz; 14.12.2020
comment
@GrijeshChauhan Короче говоря, это реализует так называемую «оценку короткого замыкания». Как правило, P ? x : y или x if P else y можно записать как (lambda:y, lambda:x)[P](), но я сомневаюсь, что он имеет лучшую производительность и, следовательно, его необходимость. - person SneezeFor16Min; 19.01.2021

a if condition else b

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

     condition
  if           else
a                   b 
person Community    schedule 06.12.2018

Одна из альтернатив условного выражения 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().

person Community    schedule 09.02.2019

Тернарный условный оператор просто позволяет проверять условие в одной строке, заменяя многострочное 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
person Community    schedule 04.04.2018
comment
Обратите внимание, что тернарный оператор меньше (в памяти) и быстрее, чем вложенный if. Кроме того, ваш вложенный if-else на самом деле не является переписыванием тернарного оператора и будет производить другой вывод для выбранных значений a и b (особенно, если один из них является типом, который реализует странный метод __ne__). - person Perkins; 11.10.2018

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

[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 вообще не будет оцениваться, так как и с 0 всегда будет оцениваться как ноль, и нет необходимости оценивать выражение. Так работает сам компилятор на всех языках.

In

1 or exp

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

Но в случае

True and exp1 or exp2

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

Аналогично в

False and exp1 or exp2

Выражение exp1 не будет оцениваться, поскольку False эквивалентно записи 0, а выполнение с 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] ;

person Community    schedule 20.08.2017
comment
Если вы хотите использовать это в контексте x = [condition] and ([expression_1] or 1) or [expression_2] и expression_1 оценивается как ложь, x будет 1, а не expression_1. Используйте принятый ответ. - person moi; 20.10.2017

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

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

, становится:

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

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

person Community    schedule 11.05.2016
comment
Я предпочитаю print( 'yes' if conditionX else 'nah' ) вашему ответу. :-) - person frederick99; 20.08.2017
comment
То есть, если вы хотите print() в обоих случаях - и это выглядит немного более питоническим, я должен признать :) Но что, если выражения / функции не совпадают - например, print('yes') if conditionX else True - чтобы получить print() только в правдивом conditionX - person Todor Minakov; 26.10.2017
comment
Чтобы добавить к замечанию Frederick99, еще одна причина избегать print('yes') if conditionX else print('nah') состоит в том, что он выдает SyntaxError в Python2. - person Thierry Lathuille; 22.10.2018
comment
Единственная причина, по которой он дает синтаксическую ошибку, заключается в том, что в Python 2 print является оператором - print "yes", а в Python 3 это функция - print("yes"). Это можно решить, используя это как утверждение, или лучше - from future import print_function. - person Todor Minakov; 22.10.2018

Как уже было сказано, да, в 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: Конечно, оценка короткого замыкания не является тернарным оператором, но часто тернарный используется в тех случаях, когда короткого замыкания будет достаточно.

person Community    schedule 16.10.2019

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

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

Оператор моржа в 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 оператор.

person Community    schedule 23.12.2020

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

<condition> ? <expression1> : <expression2>

Сначала Python B энергичный D ictator F или L ife (я, конечно, имею в виду Гвидо ван Россума ) отклонил его (как непитонический стиль), поскольку его довольно трудно понять людям, не привыкшим к 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'

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

person Community    schedule 25.12.2018

ДА, у 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")
person Community    schedule 21.10.2018
comment
Я добавил пример однострочного оператора, чтобы проверить, какое число велико, чтобы проработать его дальше. - person realmanusharma; 21.10.2018
comment
print на самом деле не лучший выбор, так как это приведет к ошибке SyntaxError в Python2. - person Thierry Lathuille; 22.10.2018
comment
@Thierry Lathuille здесь я использовал функцию print (), а не оператор печати, функция печати предназначена для Python 3, а оператор печати - для Python 2 - person realmanusharma; 22.10.2018
comment
Вопрос уже был задан по SO, просто попробуйте с Python 2, и вы убедитесь в этом сами. 'print (' hello ') - это совершенно допустимый синтаксис в Python 2.7, но способ его анализа заставляет ваш код выше генерировать SyntaxError. - person Thierry Lathuille; 22.10.2018

Другие ответы правильно говорят о тернарном операторе 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)
person Community    schedule 19.05.2020
comment
Ценное дополнение, но я не согласен: 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 является ложным. Эти два фрагмента не эквивалентны, и, следовательно, один не лучше другого. И явное лучше, чем неявное. - person ruancomelli; 20.10.2020
comment
@ruancomelli: Хорошее замечание. Я изменил ответ, чтобы отразить это исправление. - person user118967; 22.10.2020
comment
Что касается того, что это выглядело странно, мне интересно, не выглядело ли это странно для вас, потому что вы заметили неточность (что на самом деле это не было эквивалентно). Для меня это звучит естественно, потому что это напоминает мою английскую фразу: используйте то или иное (если первый вариант недоступен). Но, конечно, это субъективно. Полезно знать, что это не всем кажется естественным. - person user118967; 22.10.2020
comment
Намного лучше! И спасибо за объяснение по поводу идиомы. Мне это кажется странным, потому что я склонен думать о or как о функции, отображающей два аргумента в логическое значение, поэтому я ожидаю, что она вернет либо True, либо False (это происходит во многих других языках программирования). Но используйте тот или иной хороший мнемоник, который определенно поможет мне (и, надеюсь, другим) запомнить этот шаблон. - person ruancomelli; 28.10.2020

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, и interp рассматривает это как False в логических выражениях. Затем interp переходит и оценивает второе выражение, которое не является None и не является пустым списком, поэтому оно присваивается a.

Это также работает с пустыми списками. Например, если вы хотите назначить 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 - это язык с богатым синтаксисом и множеством идиоматических уловок, которые не сразу бросаются в глаза даблеру. Но чем больше вы изучаете и понимаете механику лежащей в основе системы, тем больше вы ее цените.

person Community    schedule 11.03.2020

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

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

person Community    schedule 12.05.2019

Синтаксис 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), но синтаксис для меня более понятен.

person Community    schedule 26.03.2020
comment
Это кажется вдвое большим объемом работы, большим использованием ОЗУ и более запутанным, чем более простой оператор val = a if cond else b. - person eatsfood; 28.04.2020
comment
Также здесь каждый раз оцениваются a и b, в отличие от a if cond else b - person Rainer Koirikivi; 11.01.2021

если переменная определена и вы хотите проверить, имеет ли она значение, вы можете просто 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
person Community    schedule 26.04.2018
comment
Хотя это полезно для подобных задач, это не тернарное условие. Работает на замену x if x else y, но не x if z else y. - person Perkins; 11.10.2018

is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

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

**

person Community    schedule 23.10.2019

person    schedule
comment
Это подчеркивает основное предназначение тернарного оператора: выбор значения. Это также показывает, что более одного тернара можно объединить в одно выражение. - person Roy Tinker; 05.10.2010
comment
@Craig, я согласен, но также полезно знать, что произойдет, если нет скобок. В реальном коде я бы тоже стал вставлять явные скобки. - person Jon Coombs; 02.12.2014
comment
Используйте 1_ - person mins; 25.10.2020