Python LanguageСравнения

Синтаксис

  • ! = - не равно

  • == - Является равным

  • > - больше, чем

  • < - меньше, чем

  • >= - больше или равно

  • <= - меньше или равно

  • is - test, если объекты являются одним и тем же объектом

  • is not = test, если объекты не являются одним и тем же объектом

параметры

параметр подробности
Икс Первый элемент для сравнения
Y Второй предмет для сравнения

Больше или меньше

x > y
x < y

Эти операторы сравнивают два типа значений, они меньше и чем операторы. Для чисел это просто сравнивает числовые значения, чтобы увидеть, что больше:

12 > 4
# True
12 < 4
# False
1 < 4
# True

Для строк они будут сравнивать лексикографически, что аналогично алфавитному порядку, но не совсем одинаково.

"alpha" < "beta"
# True
"gamma" > "beta"
# True
"gamma" < "OMEGA"
# False

В этих сравнениях строчные буквы считаются «большими» в верхнем регистре, поэтому "gamma" < "OMEGA" является ложной. Если бы они были заглавными, он бы возвращал ожидаемый результат в алфавитном порядке:

"GAMMA" < "OMEGA"
# True

Каждый тип определяет его вычисления с операторами < и > разному, поэтому вам следует исследовать, что означают операторы с заданным типом, прежде чем использовать его.

Не равен

x != y  

Это возвращает значение True если x и y не равны и в противном случае возвращает значение False .

12 != 1
# True
12 != '12'
# True
'12' != '12'
# False

Равно

x == y 

Это выражение оценивает, являются ли x и y одним и тем же значением и возвращает результат в виде логического значения. Как правило, оба типа и значения должны совпадать, поэтому int 12 не совпадает с строкой '12' .

12 == 12
# True
12 == 1
# False
'12' == '12'
# True
'spam' == 'spam'
# True
'spam' == 'spam '
# False
'12' == 12
# False

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

Сравнение цепей

Вы можете сравнить несколько элементов с несколькими операторами сравнения с целым сравнением. Например

x > y > z

это всего лишь короткая форма:

x > y and y > z

Это будет оцениваться как True только если оба сравнения равны True .

Общий вид

a OP b OP c OP d ...

Где OP представляет собой одну из нескольких операций сравнения, которую вы можете использовать, а буквы представляют собой произвольные допустимые выражения.

Заметим, что 0 != 1 != 0 значение True , хотя 0 != 0 - False . В отличие от общей математической нотации, в которой x != y != z означает, что x , y и z имеют разные значения. Операции Chaining == имеют естественное значение в большинстве случаев, так как равенство обычно является транзитивным.

Стиль

Теоретического ограничения на количество элементов и операций сравнения, которые вы используете, пока у вас есть правильный синтаксис:

1 > -1 < 2 > 0.5 < 100 != 24

Приведенное выше возвращает значение True если каждое сравнение возвращает True . Однако использование свернутого цепочки не является хорошим стилем. Хорошая цепочка будет «направленной», не более сложной, чем

1 > x > -4 > y != 8

Побочные эффекты

Как только одно сравнение возвращает False , выражение немедленно оценивает значение False , пропуская все оставшиеся сравнения.

Заметим, что выражение exp в a > exp > b будет оцениваться только один раз, тогда как в случае

a > exp and exp > b

exp будет вычисляться дважды, если a > exp истинно.

Сравнение `is` vs` == `

Типичная ошибка является запутанными операторы сравнения равенства is и == .

a == b сравнивает значения a и b .

a is b будет сравнивать тождества a и b .

Проиллюстрировать:

a = 'Python is fun!'
b = 'Python is fun!'
a == b # returns True
a is b # returns False

a = [1, 2, 3, 4, 5]
b = a      # b references a
a == b     # True
a is b     # True
b = a[:]   # b now references a copy of a
a == b     # True
a is b     # False [!!]

В принципе, is можно считать сокращением для id(a) == id(b) .

Помимо этого, существуют причуды среды выполнения, которые еще больше усложняют ситуацию. Короткие строки и маленькие целые числа возвращают True по сравнению с is , из-за того, что машина Python пытается использовать меньше памяти для идентичных объектов.

a = 'short'
b = 'short'
c = 5
d = 5
a is b # True
c is d # True

Но более длинные строки и большие целые числа будут храниться отдельно.

a = 'not so short'
b = 'not so short'
c = 1000
d = 1000
a is b # False
c is d # False

Вы должны использовать is , чтобы проверить на None :

if myvar is not None:
    # not None
    pass
if myvar is None:
    # None
    pass

Использование is заключается в проверке «дозорного» (т.е. уникального объекта).

sentinel = object()
def myfunc(var=sentinel):
    if var is sentinel:
        # value wasn’t provided
        pass
    else:
        # value was provided
        pass

Сравнение объектов

Чтобы сравнить равенство пользовательских классов, вы можете переопределить == и != __eq__ __ne__ методов __eq__ и __ne__ . Вы также можете переопределить __lt__ ( < ), __le__ ( <= ), __gt__ ( > ) и __ge__ ( > ). Обратите внимание, что вам нужно только переопределить два метода сравнения, и Python может обрабатывать остальные ( == то же самое, что и not < а not > и т. Д.).

class Foo(object):
    def __init__(self, item):
        self.my_item = item
    def __eq__(self, other):
        return self.my_item == other.my_item
    
a = Foo(5)
b = Foo(5)
a == b     # True
a != b     # False
a is b     # False

Обратите внимание, что это простое сравнение предполагает, что other (объект, сравниваемый с) является одним и тем же типом объекта. По сравнению с другим типом будет выдана ошибка:

class Bar(object):
    def __init__(self, item):
        self.other_item = item
    def __eq__(self, other):
        return self.other_item == other.other_item
    def __ne__(self, other):
        return self.other_item != other.other_item
    
c = Bar(5)
a == c    # throws AttributeError: 'Foo' object has no attribute 'other_item'

Проверка isinstance() или аналогичного isinstance() поможет предотвратить это (при желании).

Common Gotcha: Python не применяет типизацию

Во многих других языках, если вы запускаете следующий (пример Java)

if("asgdsrf" == 0) {
    //do stuff
}

... вы получите сообщение об ошибке. Вы не можете просто сравнивать строки с целыми числами. В Python это совершенно законное утверждение - это просто разрешит False .

Обычным способом является следующее:

myVariable = "1"
if 1 == myVariable:
    #do stuff

Это сравнение будет оцениваться False без ошибки, каждый раз, потенциально скрывая ошибку или нарушая условное выражение.