在Python 2中,可以通过隐式比较类型的文本字符串(即按字典顺序,字符串{来比较int
和str
等不同类型的对象{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方法以正确支持比较。
答案 0 :(得分:1)
所有这些都是有效的语句(它们的求值均为True
):
0 < True
0 < 1.
0. < True
{0} < frozenset((0, 1))
在这里看起来唯一奇怪的是0. == False
和1. == 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行为的方法。
也许您应该看看this或that。 This question还强调了2011年的变化:
发现它:埋在PEP 3100中:“除非不同类型明确支持,否则==和!=之外的其他比较将引发异常”