Сообщить об ошибке.

Операции сравнения в Python.

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

Разрешенные операции сравнения:

  • x < y - строго x меньше y,
  • x <= y - x меньше или равно y,
  • x > y - строго x больше y,
  • x >= y - x больше или равно y,
  • x == y - x равно y,
  • x != y - x не равно y.

Внимание!. Комплексным числам (тип complex) недоступны операции: x < y, x <= y, x > y и x >= y.

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

x < y <= z
# эквивалентно 
x < y and y <= z

В примере выше y вычисляется только один раз. Если x < y оказывается ложным, то в обоих случаях, приведенных выше z не оценивается вообще.

Еще пример:

a < b <= c < d
# эквивалентно 
a < b and b <= c and c < d

В такой форме сравнения легче читаются, и каждое подвыражение вычисляется по крайней мере один раз. Так же читайте о результатах смешивание операторов is и in в цепочках сравнений"

Объекты разных типов, за исключением различных числовых типов, никогда не будут равными.

Оператор == всегда определен, но для некоторых типов объектов, например объектов класса, эквивалентен оператору идентичности is.

Операторы <, <=, > и >= применяются только там, где они имеют смысл, например они вызывают исключение TypeError, когда один из аргументов является комплексным числом.

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

Экземпляры класса не могут быть упорядочены относительно других экземпляров того же класса или других типов объектов, если класс не определяет достаточное количество методов __lt__(), __le__(), __gt__() и __ge__(). В общем случае определение методов __lt__() и __eq__() для этих целей бывает достаточно.

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

  • Числа встроенных числовых типов int, float, complex и стандартных библиотечных типов fractions.Fraction и decimal.Decimal можно сравнивать внутри и между их типами, с ограничением, что комплексные числа не поддерживают сравнение порядка. В пределах задействованных типов они сравнивают математически (алгоритмически) правильно без потери точности.

    Нечисловые значения float('NaN') и decimal.Decimal('NaN') являются особыми. Любое упорядоченное сравнение числа с нечисловым значением неверно. Нечисловые значения не равны самим себе. Например, если x = float('NaN'), 3 < x, x < 3 и x == x все ложны, а x! = X истинно. Это поведение соответствует стандарту IEEE 754.

  • None и NotImplemented являются одиночными. PEP 8 советует, что сравнения для одиночных экземпляров всегда должны выполняться с использованием или нет, а не с операторами равенства.

  • Двоичные последовательности (экземпляры bytes или bytearray) можно сравнивать внутри и между их типами. Они сравнивают лексикографически, используя числовые значения своих элементов.

  • Строки (экземпляры str) лексикографически сравниваются с использованием числовых кодовых точек Unicode (результат встроенной функции ord()) их символов.

    Строки и двоичные последовательности нельзя сравнивать напрямую.

  • Последовательности (экземпляры tuple, list или range) можно сравнивать только в пределах каждого из их типов с ограничением, что диапазоны range не поддерживают сравнение порядка (сортировку). Операция равенства между этими типами приводит к неравенству, а сравнение порядка между этими типами вызывает исключение TypeError.

    Последовательности сравнивают лексикографически с помощью сравнения соответствующих элементов. Встроенные контейнеры обычно предполагают, что идентичные объекты равны самим себе. Это позволяет им обходить тесты на равенство для идентичных объектов, чтобы повысить производительность и сохранить свои внутренние инварианты.

    Лексикографическое сравнение встроенных коллекций работает следующим образом:

    • Чтобы две коллекции были равными, они должны быть одного типа, иметь одинаковую длину и каждая пара соответствующих элементов должна быть равной. Например [1,2] == (1,2) ложно, потому что типы последовательностей разные.

    • Коллекции, поддерживающие сравнение порядка (сортировку), упорядочиваются так же, как их первые неравные элементы, например [1,2, x] <= [1,2, y] имеет то же значение, что и x <= y. Если соответствующий элемент не существует, то более короткая коллекция при сортировке встанет первой, например [1,2] < [1,2,3] истинно).

  • Множества (экземпляры set или frozenset) можно сравнивать внутри и между их типами.

    Они определяют операторы сравнения порядка для обозначения тестов подмножества и надмножества. Эти отношения не определяют общий порядок. Например два множества {1,2} и {2,3} не равны, ни подмножества друг друга, ни надмножества друг друга. Соответственно, наборы не являются подходящими аргументами для функций, которые зависят от общего упорядочения. Например min(), max() и sorted() дают неопределенные результаты при наличии списка множеств в качестве входных данных.

  • Большинство других встроенных типов не имеют реализованных методов сравнения, поэтому они наследуют поведение сравнения по умолчанию.

Примеры использования операции сравнения:

>>> a = 8
>>> b = 3
>>> a == b 
# False
>>> a < b
# False
>>> a != b
# True

Цепочки из нескольких операций сравнения:

>>> a = 2
>>> b = 6
>>> c = 10
>>> a < b < c
# True
>>> a != b != c
# True
>>> a == b == c
# False
>>> 0 < b < 5
# False

Важно:

Числа типа float не являются десятичными дробями и используют двоичную арифметику, поэтому иногда выражения могут вычисляться с ничтожно малыми погрешностями. Из-за этих погрешностей операции сравнения работают не так как ожидается.

>>> 0.8 - 0.5 - 0.3 == 0 
# False
>>> 0.8 - 0.5 - 0.3
# 5.551115123125783e-17

>>> 10.5 + 4.1 + 6.4 == 21
True
>>> 10.5 + 4.1 + 6.4
# 21.0