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

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

Комментарии к вопросу (7)
Решение

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

a if condition else b

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

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

Например:

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

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

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

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

x = a if True else b

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

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


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

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

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

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

Комментарии (10)

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

(falseValue, trueValue)[test]

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

(falseValue, trueValue)[test == True]

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

(falseValue, trueValue)[bool()]
Комментарии (10)

Для версий, предшествующих 2.5, есть одна хитрость:

[expression] and [on_true] or [on_false]

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

  1. Существует ли эквивалент троичного оператора "?:" языка Си?
Комментарии (4)

< код > < i > < выражение 1 > < / i > < b > / b > < i > < условие > < / i > < b >

а = 1
б = 2

1, если > б еще -1
 # Выход -1

1, если > b еще -1, если < b еще 0
# Выход -1
Комментарии (2)

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

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

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

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

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

Комментарии (0)

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

 if  else 

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

if :  else: 

Вот пример:

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]

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

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 в Википедии < / sup >

Комментарии (1)

К сожалению,

(falseValue, trueValue)[test]

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

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

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

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

И так, история гласит: выбор между 3 упомянутыми решениями - это компромисс между наличием функции короткого замыкания, использующей, по крайней мере, Zython 2.5 (ИМХО больше не проблема) и не склонной к «trueValue» -оценкам -false "ошибки.

Комментарии (1)

Последовательный оператор на разных языках программирования


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

  • Последовательный оператор в Javascript *
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
  • Последовательный оператор в Ruby *
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
  • Почечный оператор в Скале *
val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0
  • Последовательный оператор в программировании R *

a 
Комментарии (4)

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

[on_true] if [cond] else [on_false]

У старых Питонов троичный оператор не реализован, но его можно смоделировать.

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.

Комментарии (4)

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

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
Комментарии (0)

Есть ли у 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 ожидает третье выражение для другого:

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

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

[expression1 for element in iterable if expression2]

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

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

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

expression1 if expression1 else expression2

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

expression1 or expression2

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

Комментарии (4)

Моделирование троичного оператора питона.

Например

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'
Комментарии (2)

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

[условие] и [expression_1] или [expression_2];

Пример: -

print (число% 2 и "странный" или "четный")

Это напечатало бы «странно», если число нечетное, или «четное», если число четное.


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

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

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

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

0 and exp

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

В

1 or exp

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

Но в случае

True and exp1 or exp2

Второе выражение exp2 не будет оцениваться, поскольку True и 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, сделайте это: -

[условие] и ([expression_1] или 1) или [expression_2];

Комментарии (1)

Терничный условный оператор просто позволяет протестировать условие в одной строке, заменяя многострочный 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
Комментарии (1)

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

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

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

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

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

Комментарии (4)
a if condition else b

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

     condition
  if           else
a                   b 
Комментарии (0)

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

 ?  : 

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

 if  else 

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

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

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'

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

Комментарии (0)

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

#[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")
Комментарии (5)

Одна из альтернатив Python [условное выражение][1] заключается в следующем:

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

который имеет следующее приятное расширение:

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

Кратчайший альтеративный остаток:

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

но альтернативы нет, если вы хотите избежать оценки yes () и no () в следующем:

yes() if [condition] else no()

[1]: https://mail.python.org/pipermail/python-dev/2005-сентябрь / 056846.html

Комментарии (0)

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

 if  else 

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

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

а = правда
б = ложно

# Вместо этого:
x = a, если a, b

# Вы можете использовать оценку короткого циркания:
х = а или б

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

Комментарии (1)