Ich habe eine Liste Sortierung, die ich durch mehrere key
s sortieren möchten, wie:unnötige Schlüssel Auswertungen zu vermeiden, wenn eine Liste
L = [ ... ]
L.sort(key = lambda x: (f(x), g(x)))
Das funktioniert gut. Dies führt jedoch zu unnötigen Aufrufen von g
, die ich vermeiden möchte (weil sie möglicherweise langsam sind). Mit anderen Worten möchte ich teilweise und träge den Schlüssel auswerten.
Wenn beispielsweise f
eindeutig über L
ist (d. H. len(L) == len(set(map(f,L)))
), sollten keine Aufrufe an g
vorgenommen werden.
Was wäre der eleganteste/pythonischste Weg, dies zu tun?
Ein Weg, ich denken kann, ist eine benutzerdefinierte Funktion cmp
(L.sort(cmp=partial_cmp)
) zu definieren, aber IMO ist dies weniger elegant und komplizierter als die key
Parameter.
Eine andere Möglichkeit wäre, eine Schlüssel-Wrapper-Klasse zu definieren, die einen Generatorausdruck zum Generieren der verschiedenen Teile des Schlüssels verwendet und die Vergleichsoperatoren überschreibt, um sie einzeln zu vergleichen. Aber ich fühle mich muss es ein einfacherer Weg sein ...
EDIT: Ich habe Interesse an einer Lösung für das allgemeine Problem des Sortierens von mehr Funktionen, nicht nur zwei wie in meinem Beispiel über.
Eigentlich so weit ich weiß, '' cmp' 'Version könnte langsamer sein als' 'key'' Version, da' 'key'' N-mal ausgewertet wird, und' cmp''' '' O (log (n) n) '' mal. –
@jb. Ist Pythons Sortierung nicht O (nlogn)? –
@jb interessant. Für meinen speziellen Fall können wir jedoch annehmen, dass "g" wesentlich langsamer ist als der Vergleich der Ergebnisse von "f" und "g" (außerdem kann ich die Ergebnisse in einem Wrapper-Objekt zwischenspeichern) – shx2