Guido rethinking removal of cmp from sort method

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Mar 24 19:49:53 EDT 2011


On Thu, 24 Mar 2011 17:47:05 +0100, Antoon Pardon wrote:

> However since that seems to be a problem for you I will be more
> detailed. The original poster didn't ask for cases in which cmp was
> necessary, he asked for cases in which not using cmp was cumbersome.

I'm the original poster, and that's not what I said. I said:

"If anyone has any use-cases for sorting with a comparison function that 
either can't be written using a key function, or that perform really 
badly when done so, this would be a good time to speak up."

You'll notice that I said nothing about whether writing the code was easy 
or cumbersome, and nothing about readability.


> I
> gave a case where not using cmp was cumbersome. a tuple where you want
> it sorted with first item in descending order and second item ascending.

No, I'm sorry, calling sort twice is not cumbersome. In fact, if somebody 
gave me code that sorted tuples in that way using a comparison function, 
I would immediately rip it out and replace it with two calls to sort: not 
only is it usually faster and more efficient, but it's easier to read, 
easier to reason about, and easier to write.


from operator import itemgetter
data.sort(key=itemgetter(1))
data.sort(key=itemgetter(0), reverse=True)


A cmp function for this task may have been justified back in the Dark 
Ages of Python 2.2, before Python's sort was guaranteed to be stable, but 
there's no need for it now.


> You then responded, that you could solve that by sorting in multiple
> steps. The problem with this response is that how items are to be
> compared can be decided in a different module from where they are
> actually sorted.

So what? Instead of this:

# Module A decides how to sort, module B actually does the sort.
# In module A:
B.do_sorting(cmp=some_comparison_function)

it will become this:

# In module A:
func = functools.cmp_to_key(some_comparison_function)
B.do_sorting(key=func)

That's hardly cumbersome.

I'm looking for cases where using cmp_to_key doesn't work at all, or 
performs badly, if such cases exist at all.



> First of all, there is no need for a dynamical generated cmp function in
> my provided case. My cmp fumction would simply look like this:
> 
> def cmp(tp1, tp2):
>   return cmp(tp2[0], tp1[0]) or cmp(tp1[1], tp2[1])

"Simply"?

Perhaps that works, I don't know -- but I do know that I can't tell 
whether it works by just looking at it. That makes it complex enough that 
it should have a test suite, to ensure it works the way you expect.

But regardless, nobody argues that a comparison function must always be 
complicated. Or even that a comparison function is never less complicated 
than a key function. That's not the point. The point is to find an 
example where a comparison function will work where no key function is 
either possible or practical.



-- 
Steven



More information about the Python-list mailing list