Какие есть встроенные типы Python 3, которые можно сравнивать друг с другом? - PullRequest
1 голос
/ 15 апреля 2019

В Python 2 можно было сравнивать объекты разных типов, таких как int с str, с помощью неявного сравнения текстовой строки типов (т. Е. В лексикографическом порядке строка 'int' меньше чем строка 'str' и строка 'list' меньше строки 'tuple').

Следовательно, в Python 2 5 < 'hello' возвращает True. Можно узнать больше о том, почему это было разрешено в ответ на Почему ''> 0 True в Python? .

В Python 3 возникает исключение builtins.TypeError: unorderable types: int() < str().

Эта веб-страница говорит

Строгий подход к сравнению в Python 3 делает его обычно невозможно сравнивать разные типы объектов.

Означает ли это, что есть некоторые встроенные типы или особые случаи, когда можно было бы сравнивать любые встроенные типы, не вызывая TypeError? Я не говорю о пользовательских типах, где реализованы необходимые более сложные методы для правильной поддержки сравнения.

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Я уже просматривал это в Интернете раньше, и кажется, что они действительно несовместимы в Python 3, за исключением нескольких особых случаев, упомянутых выше.

Изменение обычно проявляется в сортировочных списках: в Python 3 списки с элементами разных типов обычно не сортируются.Если вам нужно отсортировать разнородные списки или сравнить различные типы объектов, реализуйте ключевую функцию, чтобы полностью описать порядок упорядочения разнородных типов. Источник

Не знаю почему, но некоторые нашли способы воспроизвести поведение Python 2 с помощью Python 3.

Может быть, вам стоит взглянуть на это или это . Этот вопрос также выделил изменение в 2011 году:

Обнаружено: похоронен в PEP 3100: «Сравнения, отличные от == и! = Между разнородными типами, вызовут исключение, если явноподдерживается типом "

1 голос
/ 15 апреля 2019

Все это допустимые утверждения (и все они оцениваются как True):

0 < True
0 < 1.
0. < True
{0} < frozenset((0, 1))

Единственное, что может показаться странным, это то, что 0. == False и 1. == True.

С другой стороны, вы все равно можете воспроизвести то, что делает Python 2, приведя свое значение к str перед его сравнением (это также оценивается как True):

str(5) < 'hello'

Если вам действительно нужноТакое поведение вы всегда можете иметь функцию, которая будет приведение / сравнение.Таким образом, вы гарантируете, что объекты разных типов всегда будут сравниваться одинаково, что является единственным ограничением в python 2.

def lt(a, b):
    return str(a) < str(b)

Или, может быть, даже лучше, вы можете приводить только при необходимости:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    return str(a) < str(b)

С другой стороны, как предлагается в комментариях, в реализации CPython сравнение выглядит следующим образом:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    if a is None:
      return True
    if b is None: 
      return False
    if isinstance(a, numbers.Number):
      return True
    if isinstance(b, numbers.Number):
      return False
    return str(type(a)) < str(type(b))
...