Custom sorting
Sort dicts by multiple keys, use key= with tuple tie-breaking, and apply functools.cmp_to_key for a custom comparator.
- Sort a list of dicts by multiple keys using a tuple key function
- Use functools.cmp_to_key to convert a custom comparison function to a key
- Apply custom sorting to a practical "largest number" digit puzzle
Two techniques for when simple key=len or key=itemgetter('age') is not
enough: tuple keys for multi-field sorting, and cmp_to_key for arbitrary
custom comparators.
Multi-key sort and custom comparator
Why tuple keys work for multi-field sorts
Python compares tuples element by element: first by the first element, then
(only if equal) by the second, and so on. (-grade, name) sorts by grade
descending first (negating reverses order for integers) and name ascending
second. One pass, one key function, stable result.
This is usually cleaner than two-pass sorting. Use two-pass only when one key involves a comparison that cannot be cleanly expressed as a tuple — for instance, case-insensitive descending, or mixed ascending/descending on a non-numeric field.
When to use cmp_to_key
cmp_to_key is for situations where you have a comparison function — a
function cmp(a, b) that returns negative/zero/positive — and need to convert
it to a key= function. The comparison function is given two actual elements
and decides their relative order directly.
The largest_number problem is the classic example. The natural sort order of
integers does not work: 9 should come before 34, not after. The custom rule is:
a should come before b if the string ab is lexicographically greater than
ba. This rule cannot be expressed as a simple per-element key function because
it depends on both elements — hence cmp_to_key.
cmp_to_key is slower than a key= function because it must call the
comparator O(n log n) times during the sort. For large lists, try to express
the ordering as a simple key first. Use cmp_to_key only when the ordering
is inherently pairwise — like the concatenation comparison above.
Where to go next
Next: binary search variations — bisect_left, bisect_right, and the
unifying idea of binary search over any monotone function.