The cmp_to_key method returns a special object that acts as a surrogate key:
class K(object): __slots__ = ['obj'] def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return mycmp(self.obj, other.obj) < 0 def __gt__(self, other): return mycmp(self.obj, other.obj) > 0 def __eq__(self, other): return mycmp(self.obj, other.obj) == 0 def __le__(self, other): return mycmp(self.obj, other.obj) <= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) >= 0 def __ne__(self, other): return mycmp(self.obj, other.obj) != 0 def __hash__(self): raise TypeError('hash not implemented')
When sorting, each key will be compared with most of the other keys in the sequence. Is this element at position 0 lower or larger than this other object?
Whenever this happens, special hooks to the method are called, so __lt__ or __gt__ , which instead of a surrogate key turns into a call to the cmp method.
So, the list [1, 2, 3] sorted as [K(1), K(2), K(3)] , and if, say, K(1) compared with K(2) to see if K(1) below, then K(1).__lt__(K(2)) is mycmp(1, 2) < 0 , which translates to mycmp(1, 2) < 0 .
So the old cmp method worked; return -1, 0, or 1, depending on whether the first argument is lower, equal to or greater than the second argument. A surrogate key translates these numbers back to logical values ββfor comparison operators.
In no case should a surrogate key know anything about absolute positions. He should know only about one other object with which he is compared, and special method hooks provide this other object.