← Назад к вопросам

В чем разница между == и is?

1.3 Junior🔥 201 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между == и is в Python

Кратко

== — сравнивает значение объектов (что внутри) is — сравнивает идентичность объектов (это один и тот же объект в памяти?)

Детально

== (Equality)

Проверяет, равны ли значения двух объектов.

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)  # True (значения одинаковые)
print(a is b)  # False (разные объекты в памяти)

x = 5
y = 5
print(x == y)  # True
print(x is y)  # True (для малых чисел Python кэширует)

Когда Python вызывает ==, он использует метод __eq__:

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __eq__(self, other):
        return self.value == other.value

obj1 = MyClass(10)
obj2 = MyClass(10)

print(obj1 == obj2)  # True (переопределили __eq__)
print(obj1 is obj2)  # False (разные объекты)

is (Identity)

Проверяет, указывают ли обе переменные на один и тот же объект в памяти.

a = [1, 2, 3]
b = a  # Присвоили ссылку

print(a == b)  # True (значения)
print(a is b)  # True (один объект в памяти)

c = a.copy()  # Создали копию
print(a == c)  # True (значения)
print(a is c)  # False (разные объекты)

Внутри Python использует id():

print(id(a))  # Адрес объекта a в памяти
print(id(c))  # Адрес объекта c в памяти

print(a is c)  # Эквивалент: id(a) == id(c)

Примеры для заработка в памяти

Числа:

# Для целых чисел -5 до 256 Python кэширует объекты
x = 5
y = 5
print(x is y)  # True (один объект в памяти)

x = 257
y = 257
print(x is y)  # False (разные объекты, если создавать независимо)

# НО если присвоить:
a = 257
b = a
print(a is b)  # True (одна переменная)

Строки:

s1 = "hello"
s2 = "hello"
print(s1 is s2)  # True (интерн строк, Python кэширует одинаковые строки)

s3 = "hel" + "lo"
print(s1 is s3)  # Может быть True или False в зависимости от контекста

# Явное создание разных объектов:
s4 = "".join(["h", "e", "l", "l", "o"])
print(s1 is s4)  # False (разные объекты)

None:

a = None
b = None
print(a is b)  # True (есть только ОДИН объект None в Python)
print(a == b)  # True

# Правильно проверять None:
if x is None:  # ✓ Правильно
    pass

if x == None:  # ✗ Плохо, но работает
    pass

Списки:

list1 = [1, 2, 3]
list2 = [1, 2, 3]

print(list1 == list2)  # True (значения)
print(list1 is list2)  # False (разные объекты)

list3 = list1
print(list1 is list3)  # True (одна ссылка)

# Внимание на изменения:
list1.append(4)
print(list1)  # [1, 2, 3, 4]
print(list3)  # [1, 2, 3, 4] — изменилась и list3!

В контексте Data Science (NumPy и Pandas)

NumPy:

import numpy as np

a = np.array([1, 2, 3])
b = np.array([1, 2, 3])

print((a == b).all())  # True (поэлементное сравнение)
print(a is b)  # False (разные объекты)

# Правильное сравнение NumPy массивов:
print(np.array_equal(a, b))  # True
print(np.allclose(a, b))  # True (с tolerance для float)

Pandas:

import pandas as pd

df1 = pd.DataFrame({"a": [1, 2, 3]})
df2 = pd.DataFrame({"a": [1, 2, 3]})

print((df1 == df2).all().all())  # True
print(df1 is df2)  # False

# Правильное сравнение DataFrames:
print(df1.equals(df2))  # True

Когда использовать

Используй ==

  • Когда нужно сравнить значения
  • Для чисел, строк, списков, словарей
  • Для data science: NumPy, Pandas
if user_input == "yes":
    continue

if result == expected_value:
    print("Correct!")

if np.array_equal(data1, data2):
    process()

Используй is

  • Сравнение с None
  • Сравнение с True/False (не рекомендуется)
  • Проверка, что объект изменяется правильно
  • Performance-sensitive код
if x is None:  # Правильно
    x = default_value

if y is not None:  # Правильно
    process(y)

if result is True:  # Плохо
    pass

if result:  # Хорошо
    pass

Performance

is быстрее, чем ==

# is просто сравнивает адреса в памяти (O(1))
print(x is y)  # Быстро

# == может быть дорого (зависит от __eq__)
print(x == y)  # Медленнее для больших объектов

Для больших NumPy массивов:

import numpy as np
import time

a = np.random.rand(10**7)
b = a.copy()

# Медленно (поэлементное сравнение)
start = time.time()
result = (a == b).all()
print(f"==: {time.time() - start:.6f}s")

# Быстро
start = time.time()
result = a is b
print(f"is: {time.time() - start:.6f}s")

Частые ошибки

❌ Ошибка 1: Проверка None с ==

if x == None:  # ❌ Плохо
    pass

if x is None:  # ✓ Правильно
    pass

❌ Ошибка 2: Сравнение больших объектов

a = [1000000 элементов]
b = a.copy()

if a == b:  # ❌ Медленно (поэлементное сравнение)
    pass

if a is b:  # ✓ Быстро (но False, если копия)
    pass

❌ Ошибка 3: Модификация через is

a = [1, 2, 3]
b = a  # is check: True

a.append(4)  # Изменили a
print(b)  # [1, 2, 3, 4] — b тоже изменилась!

# Если нужна независимая копия:
c = a.copy()  # Теперь c не будет меняться

Для интервью

Полный ответ должен включить:

  1. Определение обеих операторов
  2. Примеры с кодом
  3. Случаи в NumPy/Pandas (если это DS позиция)
  4. Performance различия
  5. Правильное использование (особенно None)
  6. Частые ошибки

Примерный ответ: "== сравнивает значения объектов, используя метод eq, а is проверяет, указывают ли переменные на один объект в памяти. Для чисел и строк Python часто кэширует объекты, поэтому is может дать неожиданные результаты. Для None всегда нужно использовать is, а не ==. В Data Science — для NumPy/Pandas нужны специальные функции вроде np.array_equal или df.equals."