is vs == для строк: 'py'*2 и 'pypy'
@python_quizРазберем этот квиз
Коротко: в выражении слияния и сравнения строк важно различать тождество объектов (is) и равенство значений (==). Ниже разберём код квиза, объясним поведение и покажем практические примеры.
Условие (код из квиза)

Что происходит и почему
- Оператор == сравнивает значения объектов. Для строк это посимвольное сравнение — если последовательности символов одинаковы, результат True.
- Оператор is проверяет, указывают ли две переменные на один и тот же объект в памяти (тождество), а не на равные по значению объекты.
В приведённом фрагменте значение строк одинаковое: 'py' * 2 даёт строку "pypy", которая по содержанию равна литералу 'pypy'. Поэтому == вернёт True.
Но объект, созданный выражением 'py' * 2, обычно создаётся в runtime как новый объект. Литеральный 'pypy' может быть создан другим объектом (или инторниться), поэтому is, как правило, вернёт False. Однако поведение зависит от реализации и оптимизаций интерпретатора (например, CPython может интернировать некоторые строки), поэтому is не гарантирует совпадение для эквивалентных строк.
Демонстрация в интерпретаторе

Типичный вывод:

id() показывает, что объекты находятся в разных ячейках памяти.
Исключения и нюансы
- Компиляция и интернирование: смежные строковые литералы компилируются вместе:

В этом случае компилятор может создать один и тот же объект для c и d, и is даст True в некоторых версиях/сборках интерпретатора.
- Оператор * выполняется во время выполнения, поэтому 'py'*2 обычно создаёт новый объект, и совпадение по идентичности не гарантировано.
- CPython может интернировать некоторые короткие строки автоматически, но это поведение не документировано как универсальное и может менятьcя между версиями.
Как явно получить единый объект (если нужно)
Если по какой-то причине требуется, чтобы одинаковые строки были буквально одним и тем же объектом, можно использовать sys.intern:

sys.intern гарантированно помещает строку в таблицу интернированных строк и возвращает канонический объект для данного значения.
Рекомендации и вывод
- Для сравнения строк используйте == — это корректно и понятно по смыслу.
- is используйте для проверки тождественности объектов в тех случаях, когда важно именно то, что переменные ссылаются на один объект (например, проверка на None: x is None).
- Не полагайтесь на is для сравнения строк — поведение может зависеть от реализации и оптимизаций интерпретатора.
Коротко: строковые значения, полученные разными способами, могут быть равны по содержимому, но не быть тем же объектом в памяти. Для значения используйте ==; is — для объектов/одиночных синглтонов.