我在这里遇到了这个功能。
我对这将如何实现感到困惑——在不检查给定元素与其他所有感兴趣元素的比较情况下,如何知道给定元素应该是什么“位置”key
生成的函数?cmp_to_key
该cmp_to_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')
排序时,每个键都会与序列中的大多数其他键进行比较。位置 0 处的该元素是否低于或大于其他对象?
每当发生这种情况时,都会调用特殊的方法挂钩,所以__lt__
or__gt__
被调用,代理键变成对cmp
方法的调用。
所以列表[1, 2, 3]
被排序为[K(1), K(2), K(3)]
,如果,比如说,K(1)
与 比较,K(2)
看是否K(1)
更低,则K(1).__lt__(K(2))
调用 then ,将其转换为mycmp(1, 2) < 0
。
无论如何,这就是旧cmp
方法的工作方式;返回 -1、0 或 1,具体取决于第一个参数是否小于、等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值。
代理键在任何时候都不需要知道任何关于绝对位置的信息。它只需要知道它正在与之比较的另一个对象,并且特殊的方法钩子提供了另一个对象。