Ein- oder zweimal im Jahr stieß ich auf das folgende
Problem zu: Ich habe einen Typ, auf dem Vergleichsvorgänge teuer sein könnten (z. B. sind die Werte zu groß, um mich im Gedächtnis zu halten und müssen aus der Festplatte geladen werden oder Gleichheit ist schwer zu berechnen, da ein einzelner Wert viele Darstellungen haben kann, denken Sie an chemische Formeln). Dieser Typ ist Teil einer verschachtelten Datenstruktur (z. B. verschachtelte Listen oder Tupel oder eines Baumes). Manchmal stelle ich fest, dass die Vergleichsbetreiber (
usw.) Auf meinem Typ werden für einen einzelnen Vergleich mehrmals für die gleichen Werte aufgerufen.
Ich werde versuchen, das
Problem mit dem folgenden Beispiel zu veranschaulichen:
Code: Select all
class X:
comparisons = 0
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
def __gt__(self, other):
return self.value > other.value
def __eq__(self, other):
X.comparisons += 1
return self.value == other.value
def nest_a_hundred_times(value):
for i in range(100):
value = [value]
return value
print(nest_a_hundred_times(X(1)) < nest_a_hundred_times(X(0)))
print(X.comparisons)
In diesem Beispiel ist x mein Typ mit teuren Vergleichsvorgängen. Ich zähle nur die Anzahl der Male, die __eq __ () aufgerufen wird, aber auch die anderen Vorgänge möglicherweise teuer sein. Zwei ungleiche Werte des Typs werden in Einzelelementlisten ein paar Mal erstellt und verschachtelt. Also wurde __eq __ () 100 Mal bezeichnet. Ich denke, dass es tatsächlich unmöglich ist, dieses
Problem zu vermeiden, wenn nur die sechs Vergleichsbetreiber verwendet werden (
,! Als Beispiel für einen alternativen Ansatz verfügt Haskell über eine ord -Klasse, die eine Auftragsfunktion zum Vergleich von zwei Werten definiert. Auf diese Weise kann eine verschachtelte Datenstruktur verglichen werden, indem Sie auf jedem Knoten nur einmal die Bestellung aufrufen. Ist es möglich, das
Problem mit den von Python definierten Vergleichsbetreibern allein entgegen meiner Überzeugung zu vermeiden? (Ich versuche, eine Art von Ergebnissen zu vermeiden, da dies kein Leistungsproblem ist, sondern ein algorithmisches Problem). Oder muss ich meine eigenen Datenstrukturen (Listen, Tupel) erstellen und eine Auftragsfunktion auf ihnen implementieren?