可以相互比较的内置Python 3类型是什么?

时间:2019-04-15 18:08:57

标签: python python-3.x comparison operators typing

在Python 2中,可以通过隐式比较类型的文本字符串(即按字典顺序,字符串{来比较intstr等不同类型的对象{1}}小于字符串'int',字符串'str'小于字符串'list')。

因此,在Python 2中,'tuple'返回5 < 'hello'。人们可以阅读更多有关为什么允许这样做的答案Why is ''>0 True in Python?

在Python 3中,这引发了True异常。

web page

  

Python 3中严格的比较方法使其通常   无法比较不同类型的对象。

这是否意味着存在某些内置类型或特殊情况,可以在不引起builtins.TypeError: unorderable types: int() < str()的情况下比较任何内置类型?我不是在谈论自定义类型,在其中实施必要的dunder方法以正确支持比较。

2 个答案:

答案 0 :(得分:1)

所有这些都是有效的语句(它们的求值均为True):

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

在这里看起来唯一奇怪的是0. == False1. == True

另一方面,在比较之前,您仍然可以通过将值强制转换为str来重现python 2的作用(这也会评估为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))

答案 1 :(得分:1)

我以前已经在网上查找过此内容,除了上面提到的一些特殊情况外,它们似乎在Python 3中确实无法排序。

  

更改通常在排序列表中体现:在Python 3中,带有不同类型项的列表通常不可排序。   如果您需要对异构列表进行排序,或者比较不同类型的对象,请实现一个关键功能,以完整描述应如何对不同类型进行排序。
   Source

我不知道为什么,但是一些找到了使用Python 3重现Python 2行为的方法。

也许您应该看看thisthatThis question还强调了2011年的变化:

  

发现它:埋在PEP 3100中:“除非不同类型明确支持,否则==和!=之外的其他比较将引发异常”