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 существующий объект повторно или создал новый.