Why is cmp( ) useful?
Trivalued comparators are very useful when sorting. You don't just want to know whether two elements are equal; you also want to know their relative order so that you know how to rearrange them to move closer to a sorted list. This is why C (strcmp
) and Perl (cmp
) both have similar operations (in those cases for strings, but it's the same idea).
For sorting sequences of items. When you are sorting a list of items you only need to know one item is greater or less than another item.
More info here: http://wiki.python.org/moin/HowTo/Sorting/#The_Old_Way_Using_the_cmp_Parameter
I don't really get what does it mean sign of the difference of two numbers.
This means: take the difference, and then the sign of that difference. For example, if x
and y
are two numbers:
x < y
=>x - y < 0
and the function returns -1.x == y
=>x - y == 0
and the function returns 0.x > y
=>x - y > 0
and the function returns 1.
For more information on three-way comparisons, see Wikipedia.
Why cmp( ) is useful?
It isn't very useful, which is why it was deprecated (the builtin cmp
is gone and builtin sorts no longer accept one in Python 3). Rich comparison methods supplanted it:
object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)
This allows the <
symbol (and other symbols) to be overloaded comparison operators, enabling, for example, subset and superset comparisons of set objects.
>>> set('abc') < set('cba')
False
>>> set('abc') <= set('cba')
True
>>> set('abc') == set('cba')
True
>>> set('abc') >= set('cba')
True
>>> set('abc') > set('cba')
False
while it could enable the above, cmp
wouldn't allow the following:
>>> set('abc') == set('bcd')
False
>>> set('abc') >= set('bcd')
False
>>> set('abc') <= set('bcd')
False
Toy usage for cmp
Here's an interesting usage which uses its result as an index (it returns -1 if the first is less than the second, 0 if equal, and 1 if greater than):
def cmp_to_symbol(val, other_val):
'''returns the symbol representing the relationship between two values'''
return '=><'[cmp(val, other_val)]
>>> cmp_to_symbol(0, 1)
'<'
>>> cmp_to_symbol(1, 1)
'='
>>> cmp_to_symbol(1, 0)
'>'
According to the docs, you should treat cmp as if it wasn't there:
https://docs.python.org/3/whatsnew/3.0.html#ordering-comparisons
cmp
removed, equivalent operation
But you can use this as the equivalent:
(a > b) - (a < b)
in our little toy function, that's this:
def cmp_to_symbol(val, other_val):
'''returns the symbol representing the relationship between two values'''
return '=><'[(val > other_val) - (val < other_val)]