Подтвердить что ты не робот

Как работает функция cmp_to_key Python?

Я нашел эту функцию здесь.

Я сбив с толку, как это будет реализовано - как функция key, сгенерированная cmp_to_key, знает, какая "позиция" для данного элемента должна быть без проверки того, как данный элемент сравнивается с любым другим интересующим элементом

4b9b3361

Ответ 1

Метод 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 работал; return -1, 0 или 1, в зависимости от того, первый аргумент ниже, равный или превышающий второй аргумент. Суррогатный ключ переводит эти числа обратно в логические значения для операторов сравнения.

Ни в коем случае суррогатный ключ не должен знать ничего об абсолютных позициях. Он должен знать только об одном другом объекте, с которым он сравнивается, и специальные крючки метода обеспечивают этот другой объект.