В чем разница между is и == в Python
Что проверяют
Различаете ли вы идентичность и равенство и знаете ли, почему is для чисел работает обманчиво.
Как отвечать
== сравнивает значения и вызывает метод __eq__, который тип может переопределить. is сравнивает идентичность: это один и тот же объект в памяти, то есть совпадают их id().
Ловушка, из-за которой вопрос и задают, это оптимизации интерпретатора:
a = 256; b = 256
a is b # True
a = 257; b = 257
a is b # False (в интерактивной сессии)CPython держит кэш малых целых примерно от -5 до 256, и они существуют в единственном экземпляре. Похожая история со строками: короткие литералы интернируются. Отсюда is иногда случайно совпадает с == на маленьких значениях и перестаёт совпадать на больших. Это деталь реализации, на неё нельзя опираться, и в другой версии или другом интерпретаторе поведение отличается.
Правило простое: is только для синглтонов. Это None, True, False и собственные объекты-часовые. Канонический вид проверки на пустоту это if x is None, и он предпочтительнее == None по двум причинам: None существует в единственном экземпляре, а __eq__ у произвольного класса может быть переопределён так, что сравнение с None даст неожиданный результат (например, у массивов NumPy == возвращает не булево значение, а массив).
Для всего остального ==. Современный Python специально предупреждает: сравнение литерала через is выдаёт SyntaxWarning.
Полезно добавить, что is not это единый оператор, а не отрицание, и x is not None читается как задумано.
Где спотыкаются
Сравнивают строки и числа через is, потому что «в консоли работало».
Пишут if x == None вместо is None.
Не знают, что == можно переопределить, а идентичность нет.
Считают кэш малых целых частью спецификации языка.