Python: приоритеты операций
Как читать выражения со сравнениями, not, and и or; зачем нужны скобки и чем правила Python отличаются от математической записи.
В программе одно выражение может содержать арифметику, сравнения и логические операции. Чтобы вычисленная функция совпала с формулой задания, необходимо сохранить, какие части соединяет каждая операция. Приоритет определяет, как Python группирует выражение без дополнительных скобок. Скобки позволяют явно задать нужную группировку.
Сравнения, отрицание, И, ИЛИ
Среди этих операций сильнее всего связывают сравнения, затем not, затем and, затем or. Поэтому запись ниже означает: сравнить числа, отрицать результат второго сравнения, соединить результаты через И.
a == 0 and not b == 1
(a == 0) and (not (b == 1))
При a = 0 и b = 0 первое сравнение истинно, второе ложно. Отрицание превращает ложь в истину, поэтому всё выражение истинно. not b == 1 читается как not (b == 1). Скобки особенно полезны, когда отрицание относится к нескольким частям:
not (a and b)
(not a) and b
Это разные функции. При a = 0 и b = 0 первая истинна, вторая ложна: во второй записи результат И ограничен нулевым значением b.
Перенос математической формулы
В Python нет отдельных знаков импликации и эквивалентности. Для логических значений импликация A\to B записывается как (not A) or B, а эквивалентность A\equiv B — как A == B. Если вместо букв стоят выражения, они заключаются в скобки. Например, для (x\land y)\equiv z:
F = (x and y) == z
Без скобок x and y == z означает x and (y == z). При трёх нулях исходная эквивалентность истинна, а изменённое выражение ложно. Математический порядок операций нельзя переносить на похожие символы Python без проверки.
Цепочки сравнений
Цепочка 0 == a == b проверяет одновременно 0 == a и a == b. Она не означает (0 == a) == b. При a = b = 0 цепочка истинна, а выражение со скобками ложно: сначала получается True, которое сравнивается с нулём. Аналогично 0 < x < 10 проверяет две границы. Среднее выражение вычисляется один раз.
Что считается истиной
В условии if число 0 и пустые коллекции считаются ложными; ненулевые числа и непустые коллекции — истинными. Однако and и or возвращают один из своих операндов, то есть соединяемых значений. Например, 2 and 7 даёт 7, а 0 or 7 тоже даёт 7. Оператор not возвращает именно True или False.
В таблице истинности переменные принимают только нули и единицы. Для проверки ложного результата подходит if not F:, а для печати нуля или единицы — int(bool(F)). Короткое замыкание означает, что вычисление второй части иногда вообще не требуется.
Полная лестница приоритетов
Таблица читается сверху вниз, от сильного связывания к слабому. Стрелка внутри строки разделяет разные уровни; запятые перечисляют операции одного уровня.
| Операции и уровни | Назначение |
|---|---|
(…), […], {…} | Группировка и создание коллекций |
a[i], a[i:j], f(…), a.name | Индекс, срез, вызов, атрибут |
await → ** → +x, -x, ~x | Ожидание; степень; операции над одним значением |
*, @, /, //, % → +, - | Умножение, матричное умножение, деление, остаток; сложение, вычитание |
<<, >> → & → ^ → | | Сдвиги; побитовые И, исключающее ИЛИ, ИЛИ |
<, <=, >, >=, ==, !=, in, not in, is, is not | Сравнения, принадлежность, тождественность объектов |
not → and → or | Логические операции |
if … else → lambda → := | Условное выражение; создание функции; присваивание внутри выражения |
Операции одного уровня обычно группируются слева направо. Степень и условное выражение — справа налево: 2 ** 3 ** 2 означает 2 ** (3 ** 2). Для сравнений действует описанное правило цепочки.
Возможные ловушки
Степень и минус. -2 ** 2 даёт -4, а (-2) ** 2 даёт 4. При этом справа от степени допустим отрицательный показатель: 2 ** -1 даёт 0.5.
Побитовые знаки вместо логических слов. &, |, ^ и ~ работают с отдельными двоичными разрядами целых чисел. У них другой приоритет; ~0 равно -1, а не логической единице. Для логической формулы используются not, and, or.
Какие скобки сохраняют исходную формулу? Как проверить её на всех наборах нулей и единиц? Применение показано в восстановлении столбцов таблицы истинности.
Основание правил: приоритеты выражений Python ↗ и проверка истинности и логические операции ↗.