Как Python 2 сравнивает строку и int? Почему списки сравниваются больше, чем числа, а кортежи - больше, чем списки?

Следующий фрагмент аннотируется с выходом (как видно на ideone.com):

print "100" < "2"      # True
print "5" > "9"        # False

print "100" < 2        # False
print 100 < "2"        # True

print 5 > "9"          # False
print "5" > 9          # True

print [] > float('inf') # True
print () > []          # True

Может ли кто-нибудь объяснить, почему вывод как таковой?


Детали реализации

  • Является ли это поведение обязательным для спецификации языка, или это зависит от разработчиков?
  • Существуют ли различия между любыми основными реализациями Python?
  • Существуют ли различия между версиями языка Python?

Ответ 1

Из руководство python 2:

Подробности реализации CPython: объекты разных типов, кроме номеров, упорядочены по их именам типов; объекты того же типа, которые не поддерживают правильное сравнение, упорядочиваются по их адресу.

При заказе двух строк или двух числовых типов упорядочение выполняется ожидаемым способом (лексикографическое упорядочение для строки, числовое упорядочение для целых чисел).

Когда вы заказываете числовой и нецифровой тип, сначала вводится числовой тип.

>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True

Когда вы заказываете два несовместимых типа, в которых ни числовое, они упорядочены по алфавитному порядку их имен:

>>> [1, 2] > 'foo'   # 'list' < 'str' 
False
>>> (1, 2) > 'foo'   # 'tuple' > 'str'
True

>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True

Одно исключение - это классы старого стиля, которые всегда встречаются перед классами нового стиля.

>>> class Foo: pass           # old-style
>>> class Bar(object): pass   # new-style
>>> Bar() < Foo()
False

Является ли это поведение заданным спецификацией языка, или оно зависит от разработчиков?

Нет языковой спецификации. Ссылка говорит:

В противном случае объекты разных типов всегда сравниваются неравномерно и упорядочиваются последовательно, но произвольно.

Итак, это деталь реализации.

Существуют ли различия между любыми основными реализациями Python?

Я не могу ответить на этот вопрос, потому что я использовал только официальную реализацию CPython, но есть и другие реализации Python, такие как PyPy.

Существуют ли различия между версиями языка Python?

В Python 3.x поведение было изменено, так что попытка упорядочить целое число и строку вызовет ошибку:

>>> '10' > 5
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    '10' > 5
TypeError: unorderable types: str() > int()

Ответ 2

Строки сравниваются лексикографически, а разнородные типы сравниваются по имени их типа ("int" < "string"). 3.x фиксирует вторую точку, делая их несопоставимыми.

Ответ 3

CPython implementation detail: объекты разных типов, кроме номеров, упорядочены по их именам типов; объекты того же типа, которые не поддерживают правильное сравнение, упорядочиваются по их адресу.