is и == в Python: в чём разница?
В Python для сравнения можно встретить как оператор ==, так и is.
Рассмотрим простой пример:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)
print(a is b)
Результат:
True
False
Списки a и b содержат одинаковые значения, поэтому выражение a == b возвращает True. При этом сами списки были созданы отдельно. Это два разных объекта, поэтому a is b возвращает False.
Если изменить пример следующим образом:
a = [1, 2, 3]
b = a
print(a == b)
print(a is b)
то результат будет уже другим:
True
True
В данном случае новый список для b не создавался. Переменной b была присвоена ссылка на тот же объект, на который уже ссылается a.
Можно проверить это и с помощью функции id():
a = [1, 2, 3]
b = a
print(id(a))
print(id(b))
Значения id будут одинаковыми.
==отвечает на вопрос: «Одинаковые ли у объектов значения?»
isотвечает на вопрос: «Это один и тот же объект?»
Когда использовать ==
В большинстве обычных сравнений нужен именно оператор ==.
Например:
age = 25
if age == 25:
print("Возраст совпадает")
То же самое относится к строкам:
name = "Ian"
if name == "Ian":
print("Имя совпадает")
И к коллекциям:
a = [1, 2, 3]
b = [1, 2, 3]
if a == b:
print("Списки равны")
Здесь нас интересует содержимое объектов, а не то, где именно они находятся в памяти.
Когда использовать is
is имеет смысл в тех случаях, когда необходимо проверить идентичность объекта.
Наиболее распространённый пример — None:
result = None
if result is None:
print("Результата нет")
Для обратной проверки используется is not:
if result is not None:
print(result)
Именно такой вариант обычно используется в Python-коде вместо:
if result == None:
...
Почему is иногда работает с числами и строками
Иногда можно встретить такой код:
a = 10
b = 10
print(a is b)
И получить:
True
После этого может показаться, что is вполне подходит для сравнения чисел.
Однако полагаться на такое поведение не нужно. Python может повторно использовать некоторые уже созданные объекты. Это относится, например, к некоторым целым числам и строкам.
Поэтому писать:
if number is 10:
...
неправильно.
Нужно использовать:
if number == 10:
...
То же относится и к строкам:
if status == "active":
...
а не:
if status is "active":
...
Работа программы не должна зависеть от того, использовал Python существующий объект повторно или создал новый.