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

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

вопрос задан 27.12.2008
Devoted
31395 репутация

23 ответов


  • 5446 рейтинг

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

     a if condition else b
     

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

    Например:

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

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

     condition 

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


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

    • Порядок аргументов отличается от многих других языков (таких как C, Ruby, Java и т. Д.), Что может привести к ошибкам, когда люди, незнакомые с «неожиданным» поведением Python, используют его (они могут отменить порядок).
    • Некоторые считают это «громоздким», так как оно противоречит нормальному потоку мысли (сначала думая о состоянии, а затем о последствиях).
    • Стилистические причины.

    Если у вас возникли проблемы с сохранением порядка, помните, что если вы прочитаете это вслух, вы (почти) говорите, что вы имеете в виду. Например, condition читается вслух как condition .

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

    ответ дан Vinko Vrsalovic, с репутацией 199051, 27.12.2008
  • 612 рейтинг

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

     (falseValue, trueValue)[test]
     

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

     (falseValue, trueValue)[test == True]
     

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

     (falseValue, trueValue)[bool(<expression>)]
     
    ответ дан Landon Kuhn, с репутацией 27330, 22.01.2009
  • 250 рейтинг

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

     [expression] and [on_true] or [on_false]
     

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

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

    ответ дан James Brady, с репутацией 17264, 27.12.2008
  • 161 рейтинг

    expression1 if условие else expression2

     >>> a = 1
    >>> b = 2
    >>> 1 if a > b else -1 
    -1
    >>> 1 if a > b else -1 if a < b else 0
    -1
     
    ответ дан Simon Zimmermann, с репутацией 2640, 27.05.2010
  • 107 рейтинг

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

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

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

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

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

    ответ дан Michael Burr, с репутацией 277528, 27.12.2008
  • 81 рейтинг

    Оператор условного выражения в Python был добавлен в 2006 году как часть Python Enhancement Proposal 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
     

    однако это не сработает, если <expression1> if <condition> else <expression2> будет <expression1> if <condition> else <expression2> .

    Возможным обходным путем является создание <expression1> if <condition> else <expression2> и <expression1> if <condition> else <expression2> списков или кортежей, как показано ниже:

     <expression1> if <condition> else <expression2>
     

    или:

     <expression1> if <condition> else <expression2>
     

    Если вы работаете со словарями, вместо использования тернарного условного значения вы можете воспользоваться <expression1> if <condition> else <expression2> , например:

     <expression1> if <condition> else <expression2>
     

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

    ответ дан kenorb, с репутацией 59530, 5.05.2015
  • 72 рейтинг

    @up:

    К сожалению,

     (falseValue, trueValue)[test]
     

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

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

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

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

    И так происходит история: выбор между тремя упомянутыми решениями - это компромисс между функцией короткого замыкания, использующей хотя бы python 2.5 (IMHO больше не проблема) и не подвержен «trueValue-evaluation-to-false», ошибки.

    ответ дан gorsky, с репутацией 987, 6.12.2009
  • 48 рейтинг

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

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

     cond and on_true or on_false
     

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

    ответ дан Paolo, с репутацией 9681, 25.04.2012
  • 40 рейтинг

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

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

    Тернарный оператор в Скале

     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. его читабельность и удобство обслуживания.

    ответ дан Simplans, с репутацией 1463, 21.08.2016
  • 31 рейтинг

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

     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
     
    ответ дан Benoit Bertholon, с репутацией 21, 14.01.2013
  • 28 рейтинг

    Абсолютно, и это невероятно легко понять.

     general syntax : first_expression if bool_expression_is_true else second_expression
    
    Example: x= 3 if 3 > 2 else 4 
    # assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
     
    ответ дан BattleDrum, с репутацией 290, 15.07.2015
  • 21 рейтинг

    У 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: invalid syntax . Таким образом, вышеперечисленное является либо неполной логикой (возможно, пользователь ожидает отсутствие-op в ложном состоянии), либо то, что может быть предназначено, - использовать выражение2 в качестве фильтра - отмечает, что следующим является законный Python:

     or_test ['if' or_test 'else' test]
     

    or_test ['if' or_test 'else' test] работает как фильтр для понимания списка и не является тернарным условным оператором.

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

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

     or_test ['if' or_test 'else' test]
     

    or_test ['if' or_test 'else' test] придется дважды оценивать с использованием вышеуказанного использования. Он может ограничить избыточность, если это просто локальная переменная. Тем не менее, общая и исполнительская Pythonic-идиома для этого случая использования заключается в использовании короткого замыкания or_test ['if' or_test 'else' test] :

     or_test ['if' or_test 'else' test]
     

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

    ответ дан Aaron Hall, с репутацией 153756, 17.11.2015
  • 14 рейтинг

    Моделирование троичного оператора 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'
     
    ответ дан Sasikiran Vaddi, с репутацией 464, 20.11.2013
  • 9 рейтинг

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

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

    В

     1 or exp
     

    выражение exp не будет вообще оцениваться, так как «или» с 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 становится False, тогда выражение_2 будет оцениваться из-за наличия «или» между exp_1 и exp_2.

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

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

    ответ дан Natesh bhat, с репутацией 2056, 20.08.2017
  • 8 рейтинг

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

    Синтаксис:

    [on_true], если [выражение] 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
     
    ответ дан Ali Hallaji, с репутацией 330, 4.04.2018
  • 8 рейтинг
    In [1]: a = 1 if False else 0
    
    In [2]: a
    Out[2]: 0
    
    In [3]: b = 1 if True else 0
    
    In [4]: b
    Out[4]: 1
    
    ответ дан ox., с репутацией 1722, 7.05.2014
  • 8 рейтинг

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

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

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

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

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

    ответ дан Todor, с репутацией 4300, 11.05.2016
  • 7 рейтинг

    Да, вы можете использовать его так:

     is_fat = True
    state = "fat" if is_fat else "not fat"
     

    Подробнее о тернальном условном операторе

    ответ дан Daniel Taub, с репутацией 1375, 10.06.2017
  • 3 рейтинг

    Да.

     >>> b = (True if 5 > 4 else False)
    >>> print b
    True
     
    ответ дан Alejandro Blasco, с репутацией 510, 16.03.2016
  • 1 рейтинг

    Да:

    Предположим, вы хотите дать переменной x некоторое значение, если некоторый bool является истинным и аналогичным образом

    X = 5, если что-то другое x = 10

    X = [некоторое значение], если [если это истинно, первое значение оценивает] else [другое значение оценивает]

    ответ дан Elad Goldenberg, с репутацией 54, 14.05.2018
  • 0 рейтинг

    Синтаксис: оператор Ternary будет представлен как:

     [on_true] if [expression] else [on_false]
     

    например

     x, y = 25, 50
    big = x if x < y else y
    print(big)
     
    ответ дан Saurabh Chandra Patel, с репутацией 5253, 2.07.2018
  • 0 рейтинг

    если переменная определена, и вы хотите проверить, имеет ли она значение, вы можете просто 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
     
    ответ дан ewwink, с репутацией 4569, 26.04.2018
  • 0 рейтинг

    Существует тройной вариант, как указано в других ответах, но вы также можете имитировать его с помощью «или», если вы проверяете значение boolean или None:

     >>> a = False
    >>> b = 5
    >>> a or b
    5
    
    >>> a = None
    >>> a or b
    5
     
    ответ дан Meow, с репутацией 369, 8.12.2016