问题
In Python 2, it was possible to compare objects of different types such as int
to str
by having an implicit comparison of the text string of types (that is, in lexicographic order, string 'int'
is less than string 'str'
and string 'list'
is less than string 'tuple'
).
Hence, in Python 2, 5 < 'hello'
returns True
. One can read more about why this was allowed in answer to Why is ''>0 True in Python?.
In Python 3, this raises builtins.TypeError: unorderable types: int() < str()
exception.
This web page says
The strict approach to comparing in Python 3 makes it generally impossible to compare different types of objects.
Does it mean there are some built-in types or special cases where it would be possible for any built-in types to be compared without causing TypeError
? I am not talking about custom types where the necessary dunder methods are implemented to properly support comparison.
回答1:
All these are valid statements (and they all evaluate to True
):
0 < True
0 < 1.
0. < True
{0} < frozenset((0, 1))
The only thing that may look odd here is that 0. == False
and 1. == True
.
On the other hand, you can still reproduce what python 2 does by casting your value to an str
before comparing it (this also evaluate to True
):
str(5) < 'hello'
If you really need this behaviour you can always have a function that will cast/compare. That way you'll guarantee that objects of different types will always compare the same way, which seems to be the only constraint in python 2.
def lt(a, b):
return str(a) < str(b)
Or maybe even better, you can cast only when needed:
def lt(a, b):
try:
return a < b
except TypeError:
return str(a) < str(b)
On the other hand, as suggested in the comments, in CPython's implementation, it seems like comparison is done in the following way:
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))
回答2:
I had already looked this up on the web before, and it appears they are indeed unsortable in Python 3, apart from the few special cases mentionned above.
The change usually manifests itself in sorting lists: in Python 3, lists with items of different types are generally not sortable. If you need to sort heterogeneous lists, or compare different types of objects, implement a key function to fully describe how disparate types should be ordered.
Source
I don't know why, but some found ways to reproduce the behavior of Python 2 using Python 3.
Maybe you should take a look at this or that. This question also highlighted the change in 2011:
Found it: Buried in PEP 3100: "Comparisons other than == and != between disparate types will raise an exception unless explicitly supported by the type"
来源:https://stackoverflow.com/questions/55694996/what-are-built-in-python-3-types-that-can-be-compared-to-each-other