How does Python's cmp_to_key function work?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Python 3 sorting APIs are built around key functions, not comparison functions. If you still have older logic that compares two values directly, functools.cmp_to_key is the adapter that lets that code work with sorted and list.sort.
The utility is small, but the idea behind it is worth understanding. cmp_to_key does not magically make Python sort with your comparator directly; it wraps each item in an object that knows how to compare itself using your function.
Why Python Prefers Key Functions
A key function runs once per element and returns a value that Python can compare efficiently. For example, if you sort strings case-insensitively, the key can simply be str.lower.
This is usually faster and clearer than comparing pairs repeatedly. That is why Python 3 removed the old cmp argument from sorting APIs.
What cmp_to_key Actually Does
Your comparison function must accept two arguments and return:
- a negative number if the first item should come before the second
- zero if they are equal for sorting purposes
- a positive number if the first item should come after the second
Then cmp_to_key converts that function into a key factory:
The important mental model is this:
sortedcallscmp_to_key(compare_length_then_alpha).- That returns a wrapper class.
- Each input value is wrapped in an instance of that class.
- When Python compares wrappers, the wrapper methods call your comparator.
So although the API now says key=..., the wrapped objects still use your comparison logic during ordering.
A Concrete Example
Suppose you need to sort version-like strings numerically by each dot-separated part. A plain key function is possible, but a comparator can be easier to read when rules are more involved.
This prints the versions in numeric order rather than string order.
What the Wrapper Looks Like Conceptually
You usually do not need the implementation details, but conceptually it looks like this:
The real implementation defines the rich comparison methods needed by the sort machinery. That is why your comparator must behave consistently. If it says a < b, b < c, and c < a, sorting becomes unstable or surprising.
When to Use It
Use cmp_to_key when:
- you are porting Python 2 code
- you already have a comparison function with non-trivial rules
- converting the logic into a simple tuple key would make the code harder to read
If a normal key function is easy to write, prefer that. It is more idiomatic and often faster.
For example, instead of a comparator for sorting by length and then alphabetically, this key is better:
That version is direct, deterministic, and does not require pairwise comparisons.
Common Pitfalls
- Returning
TrueorFalseinstead of a negative, zero, or positive number.cmp_to_keyexpects numeric ordering semantics. - Writing a comparator that is inconsistent. Sorting assumes the comparison relation is stable.
- Using
cmp_to_keyfor cases where a tuple key would be simpler and faster. - Expecting
cmp_to_keyto call your comparator only once per item. Comparison-based sorting can call it many times.
Summary
- '
cmp_to_keyadapts an old-style two-argument comparator for Python 3 sorting APIs.' - It works by wrapping each item in an object whose comparison methods call your comparator.
- A comparator must return negative, zero, or positive values, not booleans.
- Prefer a normal key function when the ordering can be expressed clearly as a derived value.
- Reach for
cmp_to_keymainly for legacy code or genuinely complex comparison rules.
Related reading
- How does Radix Sort work?
- How does Raft deals with delayed replies in AppendEntries RPC?
- How does Raft guarantee log consistency?
- How does raft preserve safty when a leader commits a log entry and crashes before informing followers this commitment?
- How does Python's super() work with multiple inheritance?
- How does Python's super work with multiple inheritance?
- How does sorting a string in an array of strings and then sorting that array come out to be Oaslogalogs?
- How does stdsort work for list of pairs?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.