Приоритет и ассоциативность операторов в Python

Приоритет операторов Python

Комбинация значений, переменных, операторов и вызовов функций называется выражением. Интерпретатор Python может вычислить корректное выражение.

Например:

>>> 5 - 7
-2

Здесь 5 - 7 — это выражение. В выражении может быть более одного оператора.

Для вычисления таких выражений в Python существует правило приоритета. Оно определяет порядок выполнения этих операций.

Например, умножение имеет более высокий приоритет, чем вычитание.

# Умножение имеет более высокий приоритет
# чем вычитание
>>> 10 - 4 * 2
2

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

# Круглые скобки () имеют более высокий приоритет
>>> (10 - 4) * 2
12

Приоритет операторов в Python перечислен в следующей таблице. Он указан в порядке убывания (верхняя группа имеет более высокий приоритет, чем нижние).

Операторы

Значение

()

Круглые скобки

**

Возведение в степень

+x, -x, ~x

Унарный плюс, унарный минус, побитовое НЕ

*, /, //, %

Умножение, деление, целочисленное деление, остаток

+, -

Сложение, вычитание

<<, >>

Побитовые операторы сдвига

&

Побитовое И

^

Побитовое исключающее ИЛИ

|

Побитовое ИЛИ

==, !=, >, >=, <, <=, is, is not, in, not in

Сравнения, идентичность, операторы принадлежности

not

Логическое НЕ

and

Логическое И

or

Логическое ИЛИ

Рассмотрим несколько примеров:

Предположим, мы создаём блок Оператор if…else в Python, который выполняет if, когда обед — это либо fruit, либо sandwich, и только если денег больше или равно 2.

# Приоритет or и and
meal = "fruit"

money = 0

if meal == "fruit" or meal == "sandwich" and money >= 2:
    print("Lunch being delivered")
else:
    print("Can't deliver lunch")

Вывод

Lunch being delivered

Эта программа выполняет блок if, даже когда денег 0. Она не даёт нам желаемого вывода, так как приоритет and выше, чем or.

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

# Приоритет or и and
meal = "fruit"

money = 0

if (meal == "fruit" or meal == "sandwich") and money >= 2:
    print("Lunch being delivered")
else:
    print("Can't deliver lunch")

Вывод

Can't deliver lunch

Ассоциативность операторов Python

В приведённой выше таблице мы видим, что в одной группе существует более одного оператора. Эти операторы имеют одинаковый приоритет.

Когда два оператора имеют одинаковый приоритет, ассоциативность помогает определить порядок операций.

Ассоциативность — это порядок, в котором вычисляется выражение, имеющее несколько операторов с одинаковым приоритетом. Почти все операторы имеют ассоциативность слева направо.

Например, умножение и целочисленное деление имеют одинаковый приоритет. Следовательно, если оба они присутствуют в выражении, сначала вычисляется левый.

# Ассоциативность слева направо
# Вывод: 3
print(5 * 2 // 3)

# Показывает ассоциативность слева направо
# Вывод: 0
print(5 * (2 // 3))

Вывод

3
0

Примечание

Оператор возведения в степень ** имеет ассоциативность справа налево в Python.

# Показывает ассоциативность справа налево **
# Вывод: 512, так как 2**(3**2) = 2**9
print(2 ** 3 ** 2)

# Если 2 нужно сначала возвести в степень, нужно использовать ()
# Вывод: 64
print((2 ** 3) ** 2)

Мы видим, что 2 ** 3 ** 2 эквивалентно 2 ** (3 ** 2).


Неассоциативные операторы

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

Например, x < y < z не означает ни (x < y) < z, ни x < (y < z). x < y < z эквивалентно x < y and y < z и вычисляется слева направо.

Кроме того, в то время как цепочка присваиваний типа x = y = z = 1 совершенно корректна, x = y = z+= 2 приведёт к ошибке.

# Инициализация x, y, z
x = y = z = 1

# Выражение некорректно
# (Неассоциативные операторы)
# SyntaxError: invalid syntax

x = y = z+= 2

Вывод

  File "<string>", line 8
    x = y = z+= 2
             ^
SyntaxError: invalid syntax