is vs == в Python: почему одно возвращает False, другое True
@python_quizРазберем этот квиз
Короткий пример:

Что выводит этот код и почему — разберёмся подробно.
Результат выполнения
При запуске вышеуказанного кода вы получите:

То есть сначала печатается False, затем True.
Почему так происходит — разница между is и ==
- Оператор
isсравнивает идентичность объектов — возвращает True только если оба операнда указывают на один и тот же объект в памяти. - Оператор
==сравнивает значения (логика равенства определяется методом__eq__соответствующих типов).
В нашем случае z * 0 — это комплексное число 0j (тип complex). Литерал 0 — это целое число (тип int). По значениям 0j и 0 считаются равными (т.е. 0j == 0 возвращает True), но это объекты разных типов и не один и тот же объект, поэтому сравнение через is даёт False.
Демонстрация с типами и id
Чтобы наглядно увидеть, что именно сравнивается, можно вывести типы и идентификаторы объектов:

Вы увидите, что типы различаются и идентификаторы (адреса) объектов разные — следовательно is возвращает False.
Частые заблуждения и нюансы
- Нельзя использовать
isдля сравнения числовых значений — это источник скрытых ошибок.isпредназначен для проверки того, один ли это объект (например,x is None). - Для проверки значения используйте
==. - В CPython некоторые маленькие целые числа (например, в диапазоне -5..256) могут быть переиспользуемыми объектами (интернированы), и иногда
a is bдля маленьких int может вернуть True. Но это поведение реализации, не гарантируется спецификацией, и на него нельзя опираться. - Для комплексных чисел даже значение 0 представлено объектом типа complex (
0j), поэтому0j is 0никогда не будет True.
Рекомендация
- Используйте
==для сравнения значений чисел, строк и других данных. - Используйте
isтолько для проверки идентичности (обычно для сравнения с None:if x is None:).
Краткий вывод
В примере выражение z * 0 is 0 возвращает False, потому что сравниваются разные объекты (complex vs int). Выражение z * 0 == 0 возвращает True, потому что по значению ноль комплексного и ноль целого равны.