Как 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?
2 ответа
Из руководства по питону 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()
Строки сравниваются лексикографически, а разнородные типы сравниваются по названию их типа ("int"
< "string"
). 3.x исправляет вторую точку, делая их несопоставимыми.
CPython implementation detail:
Объекты разных типов, кроме номеров, упорядочены по именам типов; объекты тех же типов, которые не поддерживают правильное сравнение, упорядочены по их адресу.