# "Natural" use of cmp= in sort

Ian Kelly ian.g.kelly at gmail.com
Tue Nov 11 09:35:34 CET 2014

```On Tue, Nov 11, 2014 at 12:44 AM, Paddy <paddy3118 at gmail.com> wrote:
> Thanks Ian. The original author states "...and it is sure that the given inputs will give an output, i.e., the inputs will always be valid.", which could be taken as meaning that all inputs are sufficient, well formed, and contain all relations as their first example does.

Well, I brought it up because the start of that sentence is "There can
be multiple inequalities as answer but I need any one which is
correct...". The only way there would be more than one correct answer
would be if the inputs were only partially ordered. I take the second
part of the sentence as meaning only that the input can be safely
assumed to be consistent.

> Yes, I knew that there are cases where a cmp function is more natural than key; the idea is to squirrel out a few. We have already made the, (well reasoned in my opinion), decision to go down the key= route in Python 3. I also like to track where my algorithms might originally map to cmp=. (It is not often).

Basically any time you have a comparison that isn't easily expressed
by mapping the values to some bunch of ordered objects. As an example
of what I mean, we can easily sort alphabetically using a key
function:

sorted(items, key=str)

And we can easily sort reverse alphabetically:

sorted(items, key=str, reverse=True)

And we can easily sort alphabetically on multiple criteria:

sorted(items, key=lambda x: (str(x.last_name), str(x.first_name)))

But what if we want to combine those last two requirements? Suppose we
have a table that we want to present sorted primarily in ascending
order on one column, and secondarily in descending order on another.
We can't just add the reverse argument argument to the previous
expression, because that would reverse the sort order for both
columns. But there is no simple key function for strings that will
reverse the sort without using the reverse argument.

There are basically two ways to approach this. One is to implement a
cmp function and pass it to cmp_to_key. The other is to create a class
with comparison methods that result in the desired order, and use the
class as the key; this is really just a variation ot the cmp_to_key
approach.

```