2012-08-27 9 views
6

Wenn ich den Inhalt von zwei Array-ähnlichen Objekten vergleichen habe - list s zum Beispiel tuple s oder collection.deque s - ohne Rücksicht auf die Art der Objekte, verwende ichWas sind die besten Möglichkeiten, den Inhalt von zwei listenähnlichen Objekten zu vergleichen?

list(an_arrayish) == list(another_arrayish) 

es irgendein idiomatischer/schneller/besserer Weg dies zu erreichen? Verwendung Vergleich der entsprechenden Elemente

+1

Jede Chance von cha den Titel zu "Was ist der schnellste Weg ..."? Wenn man beide Listen als Tupel interpretiert, erhöht dies den Speicherverbrauch, und ich habe das nie als einen idiomatischen Ansatz gesehen. –

+0

Ich werde es ändern, um nach den besten Wegen zu fragen, da ich gleichermaßen an der schnellsten wie an der lesbarsten Weise interessiert bin. – Erik

Antwort

4

Vergleichen sie element:

def compare(a,b): 
    if len(a) != len(b): 
     return False 
    return all(i == j for i,j in itertools.izip(a,b)) 

Für Python 3.x verwenden zip statt

+2

Unter Verwendung des obigen Benchmarks ergibt dies Zeiten von ungefähr 9-10 Sekunden. – Ryan

+2

@minitech Dies wird erwartet, weil Python-Loops offensichtlich viel langsamer als C-Loops sind. Aber es wird niemals Ihr Gedächtnis in die Luft jagen, da es keine Verdoppelung des Speichers erfordert, wie es der Tupel/Listen-Ansatz tut. Außerdem wird es besser für Listen verschiedener Größen sein (oder solche, die sich in den ersten Artikeln unterscheiden). – JBernardo

+0

minitech: Vergleicht man zwei 1 Millionen Artikellisten, benötigt man 200ms auf meinem Rechner. Ich bin mir nicht sicher, was du tust, das dauert so lange. –

0

Tupeln und Listen werden lexikographisch verglichen. Dies bedeutet, dass jedes Element gleich zu vergleichen ist, um gleich zu vergleichen, und die zwei Sequenzen müssen vom gleichen Typ sein und haben die gleiche Länge.

sehen, dass wir nicht in die Konvention laufen einige andere Sprachen verwenden, von „hier Gleichheit bedeutet, dass wir testen, ob diese Referenzen auf das gleiche Objekt im Speicher verweisen“ würde ich mit dem == Gleichheitstest sagen kleben wird der einfachste Weg, dies zu erreichen und daher das Beste.

+1

Die andere Sprache '==' existiert in Python in der Form 'is'. – Erik

+1

@erik Das ist wahr. Ich argumentierte nicht, dass es nicht war, einfach, dass Pythons '==' Verhalten nicht in vielen anderen Sprachen vor dem Schreiben von Code wie 'my_java_string.equals (your_java_string);' für Referenzvariablen war. Da wir dieses (IMO) nettere '==' Verhalten haben, geht meine Stimme weiter, um es für den Fall zu verwenden, den Sie beschrieben haben. – chucksmash

+0

@Eric:> Andere Sprache == existiert in Python, in Form von ist

3

Tupeln erscheinen, schneller sein:

tuple(an_arrayish) == tuple(another_arrayish) 

Hier ist eine schnelle Benchmark:

>>> timeit.Timer('list(a) == list(b)', 'a, b = (1, 2, 3, 4, 5), (1, 2, 3, 4, 6)').timeit() 
2.563981056213379 
>>> timeit.Timer('list(a) == list(b)', 'a, b = [1, 2, 3, 4, 5], [1, 2, 3, 4, 6]').timeit() 
2.4739551544189453 
>>> timeit.Timer('tuple(a) == tuple(b)', 'a, b = (1, 2, 3, 4, 5), (1, 2, 3, 4, 6)').timeit() 
1.3630101680755615 
>>> timeit.Timer('tuple(a) == tuple(b)', 'a, b = [1, 2, 3, 4, 5], [1, 2, 3, 4, 6]').timeit() 
1.475499153137207