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

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

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

Brent Bradburn 10.01.2013 09:57

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

ジョージ 26.05.2011 04:48

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

user313114 16.12.2014 00:14

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

user313114 16.12.2014 00:20

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

HelloGoodbye 09.06.2016 11:11

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

sdaffa23fdsf 14.03.2018 07:20

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

Scott Martin 15.08.2018 16:25

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

Kaan E. 22.08.2020 05:58

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

mins 25.10.2020 19:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6 560
9
2 115 156
27
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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 "неожиданное" поведение использует его (они могут изменить порядок аргументов).
  • Некоторые находят его «громоздким», поскольку он идет вразрез с обычным течением мысли (сначала нужно думать о состоянии, а затем о последствиях).
  • Стилистические причины. (Хотя встроенный if может быть полезным В самом деле и сделать ваш скрипт более лаконичным, он действительно усложняет ваш код)

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

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

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

yota 25.01.2016 18:07

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

Kal Zekdor 06.03.2016 12:23

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

Kal Zekdor 15.04.2016 03:36

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

MrGeek 26.05.2017 18:31

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

Dimesio 09.08.2017 09:08

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

MrGeek 09.08.2017 12:17

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

Dimesio 11.08.2017 03:04

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

Albert van der Horst 17.06.2018 15:50

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

BeMyGuestPlease 08.09.2019 18:02

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

Baldrickk 10.10.2019 16:45

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

QtRoS 30.01.2020 14:18

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

Gerard ONeill 10.03.2020 02:35

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

Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.

The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.

See PEP 308 for more details about conditional expressions.

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

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

[expression] and [on_true] or [on_false]

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

1. Is there an equivalent of C’s ”?:” ternary operator?

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

ThomasH 21.10.2009 19:33

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

volcano 13.01.2014 11:52

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

OrangeTux 05.08.2014 16:30

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

mbomb007 19.03.2018 23:59

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

(falseValue, trueValue)[test]

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

(falseValue, trueValue)[test == True]

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

(falseValue, trueValue)[bool(<expression>)]

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

SilverbackNet 04.02.2011 05:25
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz 08.03.2012 23:31

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

martineau 31.05.2012 22:20

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

jskulski 28.05.2015 23:57

Уродливость в глазах смотрящего, и я вовсе не считаю это уродливым. Он лаконично использует тот факт, что 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).

Dr. Andrew 19.02.2016 10:49

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

JDM 01.03.2016 21:43

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

Breezer 29.11.2017 16:59

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

Baldrickk 10.10.2019 16:48

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

problemofficer 23.09.2020 13:16

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

Mark Ransom 20.10.2020 01:02

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

JDM 23.02.2021 16:40

К сожалению,

(falseValue, trueValue)[test]

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

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

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

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

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

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

Perkins 11.10.2018 20:34

<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 05.10.2010 01:14

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

Jon Coombs 02.12.2014 00:30

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

mins 25.10.2020 19:41

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

[on_true] if [cond] else [on_false]

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

cond and on_true or on_false

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

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

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

user3317 26.09.2012 13:09

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

Jonas Kölker 11.11.2013 20:11

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

Arseny 24.02.2014 15:51

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

Hucker 28.03.2019 17:08

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

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

Имитация тернарного оператора 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'

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

Grijesh Chauhan 27.12.2013 09:50

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

glglgl 13.02.2014 12:14

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

jocerfranquiz 14.12.2020 07:29

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

SneezeFor16Min 19.01.2021 13:11

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

Source: ?: in Python at Wikipedia

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

Does Python have a ternary conditional operator?

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

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

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

expression1 or expression2 похож и с теми же недостатками / положительными сторонами, что и expression1 || expression2 в javascript.
JSDBroughton 18.02.2016 16:05

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

Aaron Hall 27.05.2016 07:37

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

tchrist 26.01.2019 17:12

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

Aaron Hall 26.01.2019 21:24

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

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

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

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

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

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

frederick99 20.08.2017 09:07

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

Todor Minakov 26.10.2017 14:40

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

Thierry Lathuille 22.10.2018 00:51

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

Todor Minakov 22.10.2018 07:09

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

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

Ternary Operator in Javascript

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

Ternary Operator in Ruby

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

Ternary operator in Scala

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

Ternary operator in R programming

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

Ternary operator in Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0

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

fralau 10.01.2018 20:12

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

Albert van der Horst 17.06.2018 15:55

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

Varun Garg 05.11.2020 11:44

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

lenz 15.11.2020 23:24

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

[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 вообще не будет оцениваться, так как "or" с 1 всегда будет 1. Так что вычислять выражение exp не будет, так как результат в любом случае будет 1. (методы оптимизации компилятора).

Но в случае

True and exp1 or exp2

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

Аналогично в

False and exp1 or exp2

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


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

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

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

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

moi 20.10.2017 09:37

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

Синтаксис:

[on_true] if [expression] 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

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

Perkins 11.10.2018 20:28

если переменная определена, и вы хотите проверить, имеет ли она значение, вы можете просто 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

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

Perkins 11.10.2018 20:13

ДА, у 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.10.2018 23:45
print на самом деле не лучший выбор, так как это приведет к ошибке SyntaxError в Python2.
Thierry Lathuille 22.10.2018 00:52

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

realmanusharma 22.10.2018 00:54

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

Thierry Lathuille 22.10.2018 00:58
a if condition else b

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

     condition
  if           else
a                   b 

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

<condition> ? <expression1> : <expression2>

At first, the PythonBenevolent Dictator For Life (I mean Guido van Rossum, of course) rejected it (as non-Pythonic style), since it's quite hard to understand for people not used to C language. Also, the colon sign : already has many uses in Python. After PEP 308 was approved, Python finally received its own shortcut conditional expression (what we use now):

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

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

Одна из альтернатив 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().

Изящный способ связать несколько операторов:

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

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

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

**

it can be nested as your need. best of luck

**

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 любому списку, в котором есть элементы.

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

Я считаю громоздким синтаксис 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), но синтаксис для меня более понятен.

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

eatsfood 28.04.2020 19:57

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

Rainer Koirikivi 11.01.2021 16:22

Другие ответы правильно говорят о тернарном операторе 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)

Ценное дополнение, но я не согласен: 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 является ложным. Эти два фрагмента не эквивалентны, и, следовательно, один не лучше другого. И явное лучше, чем неявное.

ruancomelli 20.10.2020 18:21

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

user118967 22.10.2020 17:04

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

user118967 22.10.2020 17:06

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

ruancomelli 28.10.2020 22:44

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

Note that conditionals are an expression, not a statement. This means you can't use assignment statements or pass or other statements within a conditional expression

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

Другие вопросы по теме