我遇到了这个函数here。
我对如何实现这一点感到困惑 - key
生成的cmp_to_key
函数如何知道给定元素应该是什么“位置”而不检查给定元素与每个元素的比较其他感兴趣的元素?
答案 0 :(得分:40)
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__
或__gt__
,而代理键会转而调用cmp
方法。
因此列表[1, 2, 3]
的排序方式为[K(1), K(2), K(3)]
,如果K(1)
与K(2)
进行比较以查看K(1)
是否更低,那么调用K(1).__lt__(K(2))
,将其翻译为mycmp(1, 2) < 0
。
这就是旧的cmp
方法无论如何;返回-1,0或1,具体取决于第一个参数是否小于,等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值。
代理键在任何时候都不需要知道关于绝对位置的任何信息。它只需要知道与之比较的一个其他对象,并且特殊方法钩子提供其他对象。