a = [1, 2, 3, 1, 2, 3]
b = [3, 2, 1, 3, 2, 1]
a & b sollten als gleich angesehen werden, da sie genau die gleichen Elemente haben, nur in unterschiedlicher Reihenfolge.
Die Sache ist, meine tatsächlichen Listen bestehen aus Objekten (meinen Klasseninstanzen), nicht aus ganzen Zahlen.
python
algorithm
list
comparison
Johndir
quelle
quelle
len()
zuerst s überprüfen .Antworten:
O (n) : Die Counter () -Methode ist am besten (wenn Ihre Objekte hashbar sind):
O (n log n) : Die sortierte () Methode ist die nächstbeste (wenn Ihre Objekte bestellbar sind):
O (n * n) : Wenn die Objekte weder hashbar noch bestellbar sind, können Sie Gleichheit verwenden:
quelle
sorted()
, obwohl ich zugegebenermaßen nichts davon wussteCounter
. Der Interviewer bestand darauf, dass es eine effizientere Methode gab, und ich zog eindeutig eine Lücke. Nach umfangreichen Tests in Python 3 mit demtimeit
Modul wird die Sortierung in Listen mit Ganzzahlen konsistent schneller ausgeführt. Auf Listen mit 1k Artikeln, ca. 1,5% langsamer und auf Kurzlisten mit 10 Artikeln, 7,5% langsamer. Gedanken?python3.6 -m timeit -s 'from collections import Counter' -s 'from random import shuffle' -s 't=list(range(100)) * 5' -s 'shuffle(t)' -s 'u=t[:]' -s 'shuffle(u)' 'Counter(t)==Counter(u)'
sorted vs counter
. Ich bin sehr gespannt, was hier los ist.Sie können beide sortieren:
EIN Zählung Art könnte auch effizienter sein (aber es erfordert das Objekt hashable sein).
quelle
__hash__
, aber das könnte für Sammlungen unmöglich sein.sorted([0, 1j])
Wenn Sie wissen, dass die Elemente immer hashbar sind, können Sie a verwenden,
Counter()
das O (n) ist.Wenn Sie wissen, dass die Elemente immer sortierbar sind, können Sie verwenden
sorted()
O (n log n) verwenden.Im allgemeinen Fall können Sie sich nicht darauf verlassen, dass Sie sortieren können oder über die Elemente verfügen. Daher benötigen Sie einen solchen Fallback, der leider O (n ^ 2) ist.
quelle
Der beste Weg, dies zu tun, besteht darin, die Listen zu sortieren und zu vergleichen. (Die Verwendung
Counter
funktioniert nicht mit Objekten, die nicht hashbar sind.) Dies ist für Ganzzahlen unkompliziert:Bei beliebigen Objekten wird es etwas kniffliger. Wenn Sie sich für die Objektidentität interessieren, dh ob sich in beiden Listen dieselben Objekte befinden, können Sie die
id()
Funktion als Sortierschlüssel verwenden.(In Python 2.x benötigen Sie das eigentlich nicht
key=
Parameter , da Sie jedes Objekt mit jedem Objekt vergleichen können. Die Reihenfolge ist willkürlich, aber stabil, daher funktioniert es für diesen Zweck einwandfrei. Es spielt keine Rolle, in welcher Reihenfolge die Objekte sind nur, dass die Reihenfolge für beide Listen gleich ist. In Python 3 ist das Vergleichen von Objekten unterschiedlichen Typs jedoch unter vielen Umständen nicht zulässig. Beispielsweise können Sie Zeichenfolgen nicht mit Ganzzahlen vergleichen. Wenn Sie also Objekte haben von verschiedenen Typen, am besten explizit die ID des Objekts verwenden.)Wenn Sie die Objekte in der Liste nach Wert vergleichen möchten, müssen Sie zunächst definieren, was "Wert" für die Objekte bedeutet. Dann benötigen Sie eine Möglichkeit, dies als Schlüssel bereitzustellen (und für Python 3 als konsistenten Typ). Ein möglicher Weg, der für viele beliebige Objekte funktionieren würde, besteht darin, nach ihren zu sortieren
repr()
. Dies könnte natürlich viel zusätzliche Zeit und Speicheraufbaurepr()
für große Listen usw. verschwenden .Wenn die Objekte alle Ihre eigenen Typen sind, können Sie sie definieren
__lt__()
, damit das Objekt weiß, wie es sich mit anderen vergleicht. Dann können Sie sie einfach sortieren und sich nicht um denkey=
Parameter kümmern . Natürlich können Sie auch definieren__hash__()
und verwendenCounter
, was schneller sein wird.quelle
https://docs.python.org/3.5/library/unittest.html#unittest.TestCase.assertCountEqual
assertCountEqual (erste, zweite, msg = Keine)
Testen Sie, ob diese Sequenz zuerst dieselben Elemente wie die zweite enthält, unabhängig von ihrer Reihenfolge. Wenn dies nicht der Fall ist, wird eine Fehlermeldung generiert, in der die Unterschiede zwischen den Sequenzen aufgeführt sind.
Doppelte Elemente werden beim Vergleich von erstem und zweitem nicht ignoriert. Es wird überprüft, ob jedes Element in beiden Sequenzen die gleiche Anzahl hat. Entspricht: assertEqual (Zähler (Liste (erste)), Zähler (Liste (zweite))), funktioniert jedoch auch mit Sequenzen nicht zerlegbarer Objekte.
Neu in Version 3.2.
oder in 2.7: https://docs.python.org/2.7/library/unittest.html#unittest.TestCase.assertItemsEqual
quelle
Wenn die Liste Elemente enthält , die nicht hashable sind (wie zum Beispiel einer Liste von Objekten) Sie könnten in der Lage sein , die verwenden Zähler Klasse und die Funktion id () wie zum Beispiel:
quelle
Ich hoffe, dass der folgende Code in Ihrem Fall funktioniert: -
Dadurch wird sichergestellt, dass alle Elemente in den Listen
a
&b
sind, unabhängig davon, ob sie in derselben Reihenfolge vorliegen oder nicht.Zum besseren Verständnis beziehen Sie sich auf meine Antwort in dieser Frage
quelle
Wenn der Vergleich in einem Testkontext durchgeführt werden soll, verwenden Sie
assertCountEqual(a, b)
(py>=3.2
) undassertItemsEqual(a, b)
(2.7<=py<3.2
).Funktioniert auch mit Sequenzen von nicht zerlegbaren Objekten.
quelle
Lassen Sie a, b auflisten
Sie müssen sie nicht hashbar machen oder sortieren.
quelle
a
unterstütztpop
(veränderlich ist) undindex
(eine Sequenz ist). Raymond's nimmt beides nicht an, während Gnibbler's nur eine Sequenz annimmt.Die Verwendung des
unittest
Moduls bietet Ihnen einen sauberen und standardmäßigen Ansatz.quelle