В чем разница между операторами `==` и `is` в Python?

«В чем разница между операторами `==` и `is` в Python?» — вопрос из категории Python, который задают на 30% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Операторы == и is выполняют принципиально разные проверки:

  • == (оператор равенства): Сравнивает значения объектов. Вызывает метод __eq__() для определения, равны ли данные, которые хранят объекты.
  • is (оператор идентичности): Проверяет, ссылаются ли две переменные на один и тот же объект в памяти. Сравнивает идентификаторы объектов (id()).

Пример, демонстрирующий разницу:

list_a = [1, 2, 3]
list_b = list_a          # list_b — это ссылка на тот же объект
list_c = [1, 2, 3]       # list_c — новый объект с такими же значениями

print(list_a == list_b)  # True: значения одинаковы
print(list_a is list_b)  # True: это один объект (id(list_a) == id(list_b))

print(list_a == list_c)  # True: значения одинаковы
print(list_a is list_c)  # False: это разные объекты в памяти (id(list_a) != id(list_c))

Важные нюансы и best practice:

  • Кэширование мелких целых чисел и строк: Python интернирует небольшие целые числа (обычно от -5 до 256) и иногда строки для оптимизации. Поэтому a = 100; b = 100; a is b вернет True. Не полагайтесь на это поведение для сравнения значений.
  • Синглтоны None, True, False: Для сравнения с этими объектами всегда используйте is.
    if result is None:   # Правильно
    pass
    if result == None:   # Менее предпочтительно (хотя и работает)
    pass

    Главное правило: Для сравнения значений используйте ==. Для проверки, является ли переменная None, или для работы с синглтонами, используйте is.