Вопрос

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

Это было полезно?

Решение

Да, это было добавлен в версии 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.

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

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

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

(falseValue, trueValue)[test]

test нужно вернуться Истинный или ЛОЖЬ.
Возможно, безопаснее всегда реализовывать это как:

(falseValue, trueValue)[test == True]

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

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

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

[expression] and [on_true] or [on_false]

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

1. Существует ли эквивалент тернарного оператора C «?:»?

<выражение 1> если <условие> еще <выражение 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

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

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

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

Видеть ПЭП 308 для получения более подробной информации об условных выражениях.

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

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

<expression1> if <condition> else <expression2>

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

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

Вот пример:

result = x if a > b else y

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

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

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

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

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

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

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

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

result = (a > b) and x or y

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

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

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

или:

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

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

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

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

К сожалению,

(falseValue, trueValue)[test]

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

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

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

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

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

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

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

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

[on_true] if [cond] else [on_false]

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

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.

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

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 тернарный условный оператор?

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

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

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

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

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

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

Пример:-

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

Это выведет «нечетное», если число нечетное, или «четное», если число четное.


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

Примечание :- 0, None, False, пустой список, пустая строка оценивается как False.И любые данные, отличные от 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 and exp1 будет True, если exp1 не равно false.

Аналогично в

False and exp1 or exp2

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


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

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

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

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

Синтаксис:

[on_true] если [выражение] еще [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 conditionX:
    print('yes')
else:
    print('nah')

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

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

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

a if condition else b

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

     condition
  if           else
a                   b 

ДА, в 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")

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

<condition> ? <expression1> : <expression2>

Сначала Python Бдоброжелательный Ддиктатор Фили лife (я имею в виду, конечно, Гвидо ван Россума) отверг его (как непифонический стиль), так как его довольно сложно понять людям, не привыкшим к этому. C язык.Кроме того, знак двоеточия : уже имеет множество применений в Python.После ПЭП 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'

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

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

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

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

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

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

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

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

yes() if [condition] else no()

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top