Es scheint, dass sich das OP nur mit dem Fall von zwei Variablen befasst hat, aber da StackOverflow auch für diejenigen gedacht ist, die später nach derselben Frage suchen, werde ich versuchen, den allgemeinen Fall hier etwas detaillierter zu behandeln. Eine vorherige Antwort enthält bereits eine generische Antwort mit itertools.permutations()
, aber diese Methode führt zu O(N*N!)
Vergleichen, da es N!
Permutationen mit jeweils N
Elementen gibt. (Dies war die Hauptmotivation für diese Antwort)
Lassen Sie uns zunächst zusammenfassen, wie einige der Methoden in früheren Antworten auf den generischen Fall als Motivation für die hier vorgestellte Methode zutreffen. Ich werde verwenden, um auf A
zu verweisen (x, y)
und auf B
zu verweisen (a, b)
, was Tupel beliebiger (aber gleicher) Länge sein können.
set(A) == set(B)
ist schnell, funktioniert aber nur, wenn die Werte hashbar sind und Sie garantieren können, dass eines der Tupel keine doppelten Werte enthält. (ZB {1, 1, 2} == {1, 2, 2}
wie von @ user2357112 unter @ Daniel Mesejos Antwort hervorgehoben)
Die vorherige Methode kann erweitert werden, um mit doppelten Werten zu arbeiten, indem Wörterbücher mit Zählungen anstelle von Mengen verwendet werden: (Dies hat immer noch die Einschränkung, dass alle Werte hashbar sein müssen, z. B. veränderbare Werte wie list
funktionieren nicht.)
def counts(items):
d = {}
for item in items:
d[item] = d.get(item, 0) + 1
return d
counts(A) == counts(B)
sorted(A) == sorted(B)
erfordert keine hashbaren Werte, ist jedoch etwas langsamer und erfordert stattdessen bestellbare Werte. (Also zB complex
nicht funktionieren)
A in itertools.permutations(B)
Es sind keine hashbaren oder bestellbaren Werte erforderlich, aber wie bereits erwähnt, ist es komplex O(N*N!)
, sodass selbst bei nur 11 Elementen die Fertigstellung über eine Sekunde dauern kann.
Gibt es also eine Möglichkeit, so allgemein zu sein, aber geht es erheblich schneller? Warum ja, indem "manuell" überprüft wird, ob von jedem Element die gleiche Menge vorhanden ist: (Die Komplexität dieses Elements ist O(N^2)
so, dass dies auch für große Eingaben nicht gut ist. Auf meinem Computer können 10.000 Elemente eine Sekunde dauern - aber mit kleinere Eingaben, wie 10 Elemente, dies ist genauso schnell wie die anderen)
def unordered_eq(A, B):
for a in A:
if A.count(a) != B.count(a):
return False
return True
Um die beste Leistung zu erzielen, sollten Sie dict
zuerst die sorted
Methode -based ausprobieren, auf die -based-Methode zurückgreifen, wenn dies aufgrund nicht zerlegbarer Werte fehlschlägt, und schließlich auf die count
-based-Methode zurückgreifen, wenn auch dies aufgrund nicht ordnbarer Werte fehlschlägt.
x,y, a,b
es sich handelt: Sind es Ints / Floats / Strings, beliebige Objekte oder was? Wenn sie builtin Typen waren und es war möglich , sowohl zu haltenx,y
unda,b
in sortierter Reihenfolge, dann könnte man den zweiten Zweig zu vermeiden. Beachten Sie, dass beim Erstellen eines Satzes jedes der vier Elementex,y, a,b
gehasht wird, was trivial sein kann oder nicht oder Auswirkungen auf die Leistung hat, je nachdem, um welche Art von Objekten es sich handelt.