Does the sort() function work if a list contains different types?

Question

In this exercise, the sort() function is used to sort the contents of lists of like data types. What will sort() do if the list contains different data types?

Answer

Python does not guarantee that the sort() function will work if a list contains items of different data types. As long as the items can be compared using the < comparison operator, an attempt will be made to sort the list. Otherwise, an error or exception may be generated.

In the example below, the list contains a mixture of string, integer and decimal numbers. The sort() function is unable to sort the list since numbers and strings cannot be compared.

mixed = ['Adam', 1, 'Sam', 5, 'George', 3, 'dog', -2.5,  'cat']

mixed.sort()

#Results in: TypeError: '<' not supported between instances of 'int' and 'str'

Note: This used to work in Python 2, however with the move to Python 3 it no longer does.

8 Likes

But I got an Error
Traceback (most recent call last): File β€œscript.py”, line 17, in <module> mixed.sort() TypeError: unorderable types: int() < str()

This is in Py 3,

>>> mixed = ['Adam', 1, 'Sam', 5, 'George', 3, 'dog', -2.5,  'cat']
>>> mixed.sort()
Traceback (most recent call last):
  File "<pyshell#125>", line 1, in <module>
    mixed.sort()
TypeError: unorderable types: int() < str()
>>> 

Likely in version 2 it might well have played out, but we’re putting that behind us, now, as I understand it.

2 Likes

[β€˜10 Downing St.’, β€˜12 Grimmauld Place’, β€˜1600 Pennsylvania Ave’, β€˜221 B Baker St.’, β€˜42 Wallaby Way’, β€˜742 Evergreen Terrace’]

This is the result of calling sort on the list of addresses, how is it sorting here? It is neither in numerical or alphabetical order?

2 Likes

The addresses are all strings.

In sorting strings, the sort is on the numeric value of (for practical purposes) the ASCII value of the individual characters, including spaces. The initial characters are compared. If they are different, the sort concludes. If the initial characters are the same, the sort progresses to the next character, and so on.

In Python, the function ord() returns the ASCII value of a character (chr() is its inverse).

for ch in ['0', '1', '9',  ' ', 'a', 'z', 'A', 'Z']:
    print(ord(ch), end=' ')

# Output:
48 49 57 32 97 122 65 90 

So '1600 ’ is evaluated as [49, 54, 48, 48, 32], while '221 ’ is [50, 50, 49, 32]. When those lists are compared in descending order, 1600 comes first.

If initial characters are the same, the lists are compared until there is a differing character, thus '10 and β€˜12’ come out in the expected order, although β€˜42’ is after β€˜10’, β€˜12’, β€˜1600’, and β€˜221’

As you can see, lowercase and uppercase letters would sort differently also, so to sort addresses as you expect to see them, streets together, addresses numerically sorted, will take some extra coding!

6 Likes