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[0]))
[(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[0]
...   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.

Comments

Joseph G. Mitzen

Nice solution! I guess you could make it even messier with a lambda:

sorted(items, key=lambda item: ('' if isinstance(item[0], int) else '0',)+item)

Steve Fink

Or use a tuple as a key:

  sorted(items, key=lambda x: (isinstance(x[0], str), x[0]))

but it seems like it'd be better to not have mixed types in the first place.

Philippe Ombredanne

This is one more reason why Python3 is not really Python

Nicolas

What about integer to tuple comparison?
Python 2 could sort the following, while Python 3 could not. Any suggestions are appreciated.

(1, (11, 8, 7, 6, 2)) # high card 11 (rank5)
(1, (12, 11, 8, 7, 2)) # high card 12 (rank4)
((3, 2), (11, 12)) # full house (triple and pair) (rank1)
((2, 1, 1, 1), (12, 11, 7, 6)) # pair of 12 (rank3)
((3, 1, 1), (12, 6, 3)) # three of 12 (rank2)

Your email will never ever be published.

Previous:
How I do deployments December 16, 2013 Linux, Web development
Next:
Advanced live-search with AngularJS February 4, 2014 JavaScript
Related by category:
How I run standalone Python in 2025 January 14, 2025 Python
get in JavaScript is the same as property in Python February 13, 2025 Python
How to resolve a git conflict in poetry.lock February 7, 2020 Python
Best practice with retries with requests April 19, 2017 Python
Related by keyword:
How to sort case insensitively with empty strings last in Django April 3, 2022 Python, Django, PostgreSQL
Cope with JSONDecodeError in requests.get().json() in Python 2 and 3 November 16, 2016 Python
Find the largest node_modules directories with bash September 30, 2022 Linux, Bash, macOS
How to count the most common lines in a file October 7, 2022 Linux, Bash, macOS