Почему sorted(items) == items при __lt__ всегда возвращает False
@python_quizРазберем этот квиз
Кратко: в приведённом коде сортировка вернёт True потому, что метод сравнения __lt__ всегда отдаёт False, а Timsort в Python стабилен — порядок равнозначных элементов сохраняется.
Исходный код

Вывод этой программы — True.
Пошаговый разбор: что происходит при сортировке
- sorted(items) вызывает алгоритм сортировки (в CPython — Timsort).
- Для определения порядка между двумя объектами используется вызов a.
__lt__(b). - В нашем классе
__lt__всегда возвращает False для любой пары. - Если для пары (a, b) и (b, a) оба вызова
__lt__дают False, элементы считаются «не меньшими» друг друга — по сути равными с точки зрения порядка. - Timsort — стабильный: при равенстве ключей он сохраняет исходный относительный порядок элементов.
- Поэтому отсортированный список содержит те же объекты в том же порядке, что и исходный.
- Оператор == для списков сравнивает элементы попарно с помощью их
__eq__. Поскольку объекты одинаковы по значению v (или, точнее, те же объекты в том же порядке), сравнение возвращает True.
Важно: sorted возвращает новый список, но элементы в нём — те же самые объекты (те же ссылки), поэтому и сравнение через __eq__ проходит ожидаемо.
Почему не происходит TypeError
TypeError при сортировке возникает, если сравнение между элементами не определено (например, __lt__ возвращает NotImplemented или отсутствует и сравнение стремится быть выполнено, но не может). В нашем случае __lt__ явно возвращает булево False — это валидный результат, и исключения не возникает.
Пример, когда будет TypeError:

Этот код приведёт к TypeError: '<' not supported between instances of 'Item2' and 'Item2', потому что возвращаемое NotImplemented заставляет интерпретатор искать обратный вызов или посчитать сравнение невозможным.
Анализ вариантов (почему другие мысли неверны)
- "Выведет False, потому что
__lt__всегда возвращает False" — неверно, потому что возвращение False не означает, что элементы переставляются; при равенстве ключей стабильная сортировка сохраняет исходный порядок. - "Выведет True, потому что sorted не использует
__lt__" — неверно, sorted использует__lt__для упорядочивания, просто в данном случае__lt__всегда False. - "Будет исключение
TypeErrorиз-за некорректного__lt__" — неверно для данного кода:__lt__корректно возвращает булево значение;TypeErrorвозник бы, если бы__lt__возвращал NotImplemented или был отсутствующим/неподдерживаемым для сравнения.
Небольшие дополнения по устойчивости и консистентности сравнений
- Стабильность сортировки (Timsort) — ключевой фактор: если набор элементов «равен» с точки зрения отношения <, их относительный порядок не меняется.
- Важно, чтобы поведение
__lt__и__eq__было логически совместимо. Если__eq__говорит, что элементы не равны, а__lt__делает их «равными» (все сравнения False), это может привести к неожиданному порядку. - Лучше реализовывать сравнение через ключи: вместо сложной логики в
__lt__писать key-функцию для sorted, это проще и надёжнее.
Практическая рекомендация
Если вам нужно определить порядок для объектов, реализуйте либо:
__lt__в соответствии с ожидаемой транзитивностью/антисимметрией, либо- используйте аргумент key в sorted, например:

Это гораздо понятнее и безопаснее, чем оставлять __lt__ с неконсистентным поведением.
Вывод
Когда __lt__ всегда возвращает False, элементы считаются равными для цели сортировки, а стабильный алгоритм сохраняет исходный порядок — поэтому сравнение отсортированного списка с оригиналом возвращает True. TypeError в таком коде не возникает, потому что сравнение возвращает валидное булево значение.