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

Долганов Ян Львович
Долганов Ян Львович
Junior Python Developer

Мои научные интересы сосредоточены на разработке на Python, программной инженерии, backend-разработке и современных подходах к проектированию и созданию надёжных программных систем.