Sorting mixed type lists in Python 3
18 January 2014
Because this bit me harder than I was ready for, I thought I'd make a note of it for the next victim.
In Python 2, suppose you have this:
Python 2.7.5 >>> items = [(1, 'A number'), ('a', 'A letter'), (2, 'Another number')]
Sorting them, without specifying how, will automatically notice that it contains tuples:
Python 2.7.5 >>> sorted(items) [(1, 'A number'), (2, 'Another number'), ('a', 'A letter')]
This doesn't work in Python 3 because comparing integers and strings is not allowed. E.g.:
Python 3.3.3 >>> 1 < '1' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: int() < str()
You have to convert them to stings first.
Python 3.3.3 >>> sorted(items, key=lambda x: str(x)) [(1, 'A number'), (2, 'Another number'), ('a', 'A letter')]
If you really need to sort by
1 < '1' this won't work. Then you need a more complex key function. E.g.:
Python 3.3.3 >>> def keyfunction(x): ... v = x ... if isinstance(v, int): v = '0%d' % v ... return v ... >>> sorted(items, key=keyfunction) [(1, 'A number'), (2, 'Another number'), ('1', 'Actually a string')]
That's really messy but the best I can come up with at past 4PM on Friday.