Что такое тернарный оператор в Python?

Я слышал, что в Python есть оператор, который называется тернарный оператор, но я не знаю, как его использовать. Что делает тернарный оператор?

Тернарный оператор Python (или условное выражение) работает с тремя операндами и позволяет записать логику оператора if else в одной строке кода. С помощью тернарного оператора вы указываете выражение, вычисляемое, если условие истинно, само условие и выражение, вычисляемое, если условие ложно.

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

Синтаксис тернарного оператора или условного выражения в Python следующий:

<expression_if_condition_is_true> if condition else <expression_if_condition_is_false>

Выражение, вычисляемое тернарным оператором, зависит от логического значения условия.

Примечание: для тех, кто не знаком с логическими значениями, булева переменная может иметь только два значения: True или False.

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

Если значение success равно True, мы возвращаем строку «Операция выполнена успешно», в противном случае мы возвращаем строку «Операция выполнена неудачно».

>>> success = True
>>> "Operation successful" if success else "Operation failed"
'Operation successful'

А вот что происходит, если успех — Ложь:

>>> success = False
>>> "Operation successful" if success else "Operation failed"
'Operation failed'

Как видите, условие в троичном выражении следующее:

if success

Это эквивалентно написанию…

if success == True

Давайте это подтвердим…

>>> success = True
>>> "Operation successful" if success == True else "Operation failed"
'Operation successful'
>>> success = False
>>> "Operation successful" if success == True else "Operation failed"
'Operation failed'

Почему оператор называется тернарным?

Если вам интересно, почему это называется тернарным оператором, вот ответ…

Название тернарный оператор происходит от того факта, что этот оператор работает с тремя операндами. Три операнда это:

  • Выражение вычисляется, если условие истинно.
  • Само состояние
  • Выражение оценивается, если условие ложно.

Это эквивалентно оператору if else, и преимущество в том, что он написан в одну строку.

Присвоение значения тернарного выражения переменной

В предыдущем разделе мы рассмотрели, как использовать тернарный оператор.

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

Давайте посмотрим, как сохранить значение, возвращаемое предыдущим тернарным выражением, в переменной.

>>> success = True
>>> message = "Operation successful" if success else "Operation failed"
>>> print(message)
Operation successful

Переменная message теперь содержит значение, возвращаемое тернарным выражением.

Сокращенное тернарное выражение Python

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

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

Успешный сценарий

>>> connection_output = "Connection OK"
>>> message = connection_output or "Connection Failed"
>>> print(message)
Connection OK

Сценарий неудачи

>>> connection_output = None
>>> message = connection_output or "Connection Failed"
>>> print(message)
Connection Failed

Как вы можете видеть в сценарии сбоя, сокращенный тернарный оператор возвращает строку «Connection Failed», поскольку значение переменной connection_output равно None.

Лучше ли тернарный оператор, чем оператор If-Else?

Я хочу сравнить, как одну и ту же условную логику можно записать с использованием тернарного оператора и стандартного оператора if-else.

Вот тернарный оператор, над которым мы будем работать:

message = "Operation successful" if success else "Operation failed"

А вот как это можно записать, используя оператор if-else:

if success:
    message = "Operation successful"
else:
    message = "Operation failed"

Примечание: для выполнения приведенного выше кода обязательно задайте логическое значение переменной success.

Если вы не укажете значение переменной success, вы увидите следующую ошибку:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'success' is not defined

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

Это очень круто!

Стоит ли использовать тернарный оператор? Пример с несколькими условиями

Тернарный оператор позволяет сделать ваш код более лаконичным.

Это помогает записать в одну строку ту же логику, которая потребовала бы нескольких строк при использовании стандартных операторов if-else.

При написании простых условных выражений может быть полезно использовать тернарный оператор для сокращения длины кода.

Но…

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

Вот пример с несколькими условиями:

expression1 if condition1 else expression2 if condition2 else expression3

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

message = "x smaller than 10" if x < 10 else "x greater than 10" if x > 10 else "x equal to 10"

Ого…какая длинная строка кода!

Давайте проверим!

>>> x = 6
>>> message = "x smaller than 10" if x < 10 else "x greater than 10" if x > 10 else "x equal to 10"
>>> print(message)
x smaller than 10

>>> x = 13
>>> message = "x smaller than 10" if x < 10 else "x greater than 10" if x > 10 else "x equal to 10"
>>> print(message)
x greater than 10

>>> x = 10
>>> message = "x smaller than 10" if x < 10 else "x greater than 10" if x > 10 else "x equal to 10"
>>> print(message)
x equal to 10

Код работает нормально, но троичное выражение становится все труднее читать.

Вот как выглядит стандартный if else для реализации той же логики:

if x < 10:
    message = "x smaller than 10"
else:
    if x > 10:
        message = "x greater than 10"
    else:
        message = "x equal to 10"    

Выполните его в оболочке Python, чтобы протестировать этот код, присваивая различные значения x так же, как мы делали это раньше.

Этот код намного проще читать, и мы можем улучшить его с помощью оператора Python elif:

if x < 10:
    message = "x smaller than 10"
elif x > 10:
    message = "x greater than 10"
else:
    message = "x equal to 10"

Теперь стало еще лучше, я предпочитаю эту последнюю реализацию первоначальному тернарному оператору.

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

И в этом случае использование if-elif-else делает наш код намного чище.

Тернарный оператор Python с использованием кортежей

Также можно записать тернарный оператор более коротким способом, используя кортеж Python.

Чтобы увидеть, как работает этот синтаксис, начнем с базового синтаксиса тернарного оператора:

Если условие истинно

>>> x = 1
>>> y = 2
>>> x if x > 0 else y
1

Если условие ложно

>>> x = -1
>>> y = 2
>>> x if x > 0 else y
2

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

Если условие истинно

>>> x = 1
>>> y = 2
>>> (y, x)[x > 0]
1

Если условие ложно

>>> x = -1
>>> y = 2
>>> (y, x)[x > 0]
2

Тернарный оператор, использующий кортеж, возвращает тот же результат, что и стандартный тернарный оператор.

Но почему?

Когда вы видите этот тернарный оператор кортежа впервые, это может немного сбивать с толку.

Чтобы понять, как это работает, вам сначала нужно узнать, как логические значения True и False представляются в виде целых чисел в Python.

Давайте воспользуемся оболочкой Python и преобразуем True и False в целые числа с помощью встроенного класса int().

>>> int(True)
1
>>> int(False)
0

Как показано выше, True соответствует 1, а False — 0.

Мы можем использовать вывод условия в качестве индекса для доступа к одному из элементов кортежа

…если условие возвращает 0 (Ложь), мы получаем доступ к первому элементу кортежа, в противном случае — ко второму элементу.

Это также объясняет, почему элементы кортежа в нашем примере переставлены местами:

(y, x)[x > 0]

Имеет ли это смысл?

Тернарный оператор быстрее, чем оператор if-else?

Лучший способ выяснить, работает ли тернарный оператор быстрее стандартного оператора if-else, — сравнить производительность двух подходов.

Используя модуль timeit, мы сравним следующее троичное выражение…

result = x if x > 0 else y

…следующий оператор if else:

if x > 0:
    result = x
else:
    result = y

и троичное выражение ниже, использующее кортеж:

(y, x)[x > 0]

Создайте файл Python с именем ternary_operator_performance.py со следующим кодом:

def ternary_operator(x, y):
    result = x if x > 0 else y
    return result

def if_else_statement(x, y):
    if x > 0:
        result = x
    else:
        result = y

    return result

def ternary_tuple(x, y):
    result = (y, x)[x > 0]
    return result

Затем используйте модуль timeit для измерения времени выполнения трех функций:

Тернарный оператор

$ python -m timeit -s "from ternary_operator_performance import ternary_operator" "ternary_operator(1, 2)"
10000000 loops, best of 3: 0.0503 usec per loop

Стандартный оператор if else

$ python -m timeit -s "from ternary_operator_performance import if_else_statement" "if_else_statement(1, 2)"
10000000 loops, best of 3: 0.051 usec per loop

Троичное выражение с использованием кортежа

$ python -m timeit -s "from ternary_operator_performance import ternary_tuple" "ternary_tuple(1, 2)"
10000000 loops, best of 3: 0.0688 usec per loop

Самым быстрым является базовый тернарный оператор, за которым следует оператор if-else, а затем тернарное выражение с кортежем.

Заключение

Теперь вы знаете все, что нужно для использования тернарного оператора…

…в этот момент вы можете выбрать: будете ли вы использовать тернарный оператор или стандартный оператор if-else?

Независимо от того, что вы используете, убедитесь, что ваш код чист.

Это облегчит вам жизнь и жизнь тех, кто будет читать ваш код 🙂