Поведение операторов is и == для целых чисел в Python
@python_quizРазберем этот квиз
Короткий заголовок: Понимание is vs == и кэширования целых чисел
Условие (код)

Нужно понять, какое логическое тройное значение выведет этот код и почему.
Что проверяют операции
- is — проверяет тождество объектов (идентичность, одна и та же ячейка в памяти).
- == — проверяет равенство по значению (для чисел — совпадение числового значения).
Для чисел чаще всего интересна именно семантика ==; is в основном применяется для проверки на одиночные объекты (например, None).
Почему a is b дает True
В реализациях CPython для часто используемых небольших целых чисел применяется кэширование (интернирование). По умолчанию диапазон таких закэшированных целых — от -5 до 256 включительно. При выполнении

оба имени получают ссылку на один и тот же предсозданный объект со значением 256, поэтому a is b — True.
Почему c is 257 дает False, а c == 257 — True
При выполнении

число 257 создаётся во время выполнения (runtime) как новый объект целого. Литерал 257 в коде и объект, созданный вызовом int('257'), скорее всего не будут являться одним и тем же объектом с точки зрения идентичности (особенно потому, что 257 выходит за пределы стандартного кэша -5..256). Поэтому c is 257 — False, однако значение равно, поэтому c == 257 — True.
Демонстрация (с id для ясности)

Запуск этого кода в CPython даст:
- True
- True (для сравнения значений)
- False (для is при 257)
и соответствующие id будут различаться для 257.
Важно: детали кэширования — внутренняя реализация CPython. Поведение сравнения через is для больших чисел не гарантируется одинаковым во всех реализациях Python, поэтому полагаться на is для числовых сравнений нельзя.
Анализ вариантов (что выводит программа)
Если перечислить возможные триады логических значений:
- True True True — такое поведение означало бы, что и a is b, и c is 257 оба True (неверно из-за 257 вне кэша).
- True False True — соответствует ожидаемому поведению: a и b — тот же объект (True), c не тот же объект, что литерал 257 (False), но равны по значению (True).
- False False True — противоречит тому, что a и b ссылаются на кэшированный 256.
- True False False — противоречит тому, что c == 257 (значения должны быть равны).
Исходя из описанного механизма, корректная тройка — True False True.
Практическое правило
- Используйте == для сравнения чисел по значению.
- is применяйте только для проверки идентичности синглтонов (например, x is None).
- Не полагайтесь на поведение is для целых чисел, выходящих за пределы кэшируемого диапазона; оно зависит от внутренностей реализации Python.
Итог
Код демонстрирует разницу между идентичностью объектов и равенством значений, а также показывает эффект кэширования малых целых в CPython. Резюмируя: a и b указывают на один и тот же закэшированный объект 256, а объект, полученный через int('257'), хотя и равен по значению литералу 257, является другим объектом в памяти.