Sposób cmp_to_key
zwraca szczególną obiekt, który działa jako klucz zastępczy:
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')
Przy sortowaniu, każdy klucz dostanie w porównaniu do większości innych klawiszy w sekwencji. Czy ten element w pozycji 0 jest niższy lub większy niż ten inny obiekt?
Kiedy to nastąpi, wywoływane są specjalne haki metod, więc wywoływana jest __lt__
lub __gt__
, a klucz zastępczy zamienia się w wywołanie metody cmp
.
więc lista jest sortowana [1, 2, 3]
jak [K(1), K(2), K(3)]
, a jeśli, powiedzmy, K(1)
jest porównywana z K(2)
aby zobaczyć czy K(1)
jest niższa, a następnie K(1).__lt__(K(2))
nazywa, które są tłumaczone na mycmp(1, 2) < 0
.
W ten sposób stara metoda cmp
działała w każdym razie ; return -1, 0 lub 1 w zależności od tego, kto pierwszy argument jest niższy, równy lub większy niż drugi argument. Klucz zastępczy przekształca te liczby z powrotem na wartości logiczne dla operatorów porównania.
W żadnym punkcie zastępczy klucz nie musi nic wiedzieć o pozycjach bezwzględnych. Musi tylko wiedzieć o innym obiekcie, z którym jest porównywany, a specjalne haki metody zapewniają ten inny obiekt.
Wow, rzeczywistą instancją było to, że Java ma znacznie prostsze rozwiązanie tego samego problemu niż Python. Nie ma ich wiele. – jeremyjjbrown
@jeremyjjbrown: funkcja 'cmp_to_key' istnieje tylko w celu obsługi starszych algorytmów sortowania. Prostsza metoda pythonic polega na użyciu funkcji 'key' zamiast' sorted() '. –
Czasami bardzo trudno wymyślić 'klucz', ale łatwo wymyślić funkcję porównania ... np. Chcę posortować listę liczb tak, aby wszystkie liczby nieparzyste były pierwsze, w porządku rosnącym, a następnie wszystkie liczby parzyste są następne, w malejącej kolejności. – rlbond