Comparison of different types
suggest changeObjects of different types can be compared. The results are arbitrary, but consistent. They are ordered such that None
is less than anything else, numeric types are smaller than non-numeric types, and everything else is ordered lexicographically by type. Thus, an int
is less than a str
and a tuple
is greater than a list
:
[1, 2] > 'foo'
# Out: False
(1, 2) > 'foo'
# Out: True
[1, 2] > (1, 2)
# Out: False
100 < [1, 'x'] < 'xyz' < (1, 'x')
# Out: True
This was originally done so a list of mixed types could be sorted and objects would be grouped together by type:
l = [7, 'x', (1, 2), [5, 6], 5, 8.0, 'y', 1.2, [7, 8], 'z']
sorted(l)
# Out: [1.2, 5, 7, 8.0, [5, 6], [7, 8], 'x', 'y', 'z', (1, 2)]
An exception is raised when comparing different (non-numeric) types:
1 < 1.5
# Out: True
[1, 2] > 'foo'
# TypeError: unorderable types: list() > str()
(1, 2) > 'foo'
# TypeError: unorderable types: tuple() > str()
[1, 2] > (1, 2)
# TypeError: unorderable types: list() > tuple()
To sort mixed lists in Python 3 by types and to achieve compatibility between versions, you have to provide a key to the sorted function:
>>> list = [1, 'hello', [3, 4], {'python': 2}, 'stackoverflow', 8, {'python': 3}, [5, 6]]
>>> sorted(list, key=str)
# Out: [1, 8, [3, 4], [5, 6], 'hello', 'stackoverflow', {'python': 2}, {'python': 3}]
Using str
as the key
function temporarily converts each item to a string only for the purposes of comparison. It then sees the string representation starting with either \[
, \'
, \{
or 0-9
and it’s able to sort those (and all the following characters).