46

我在这里遇到了这个功能。

我对这将如何实现感到困惑——在不检查给定元素与其他所有感兴趣元素的比较情况下,如何知道给定元素应该是什么“位置”key生成的函数?cmp_to_key

4

1 回答 1

63

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,具体取决于第一个参数是否小于、等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值。

代理键在任何时候都不需要知道任何关于绝对位置的信息。它只需要知道它正在与之比较的另一个对象,并且特殊的方法钩子提供了另一个对象

于 2013-05-03T15:44:27.470 回答