Was macht Sets schneller als Listen?


70

Das Python-Wiki sagt: "Das Testen der Mitgliedschaft mit Mengen und Wörterbüchern ist viel schneller, O (1), als das Suchen von Sequenzen, O (n). Beim Testen von" a in b "sollte b eine Menge oder ein Wörterbuch anstelle einer Liste oder sein Tupel. "

Ich habe Sets anstelle von Listen verwendet, wenn Geschwindigkeit in meinem Code wichtig ist, aber in letzter Zeit habe ich mich gefragt, warum Sets so viel schneller sind als Listen. Könnte jemand erklären oder mich auf eine Quelle verweisen, die erklären würde, was genau hinter den Kulissen von Python vor sich geht, um Sets schneller zu machen?


6
Ein Nudge- Hash-Tisch
Austin Salonen

Antworten:


104

Sets werden mithilfe von Hash-Tabellen implementiert . Wann immer Sie einem Set ein Objekt hinzufügen, wird die Position im Speicher desset Objekts anhand des Hashs des bestimmt. Beim Testen der Mitgliedschaft muss lediglich geprüft werden, ob sich das Objekt an der durch seinen Hash bestimmten Position befindet. Die Geschwindigkeit dieser Operation hängt also nicht von der Größe des Satzes ab. Im Gegensatz dazu muss bei Listen die gesamte Liste durchsucht werden, was mit zunehmender Liste langsamer wird.

Dies ist auch der Grund, warum Sets die Reihenfolge der hinzugefügten Objekte nicht beibehalten.

Beachten Sie, dass Sätze im Allgemeinen nicht schneller als Listen sind. Der Mitgliedschaftstest für Sätze ist schneller, ebenso wie das Entfernen eines Elements. Solange Sie diese Vorgänge nicht benötigen, sind Listen häufig schneller.


163

list: Stellen Sie sich vor, Sie suchen in Ihrem Schrank nach Ihren Socken, wissen aber nicht, in welcher Schublade sich Ihre Socken befinden. Sie müssen also Schublade für Schublade suchen, bis Sie sie finden (oder vielleicht nie). Das nennen wir O(n), denn im schlimmsten Fall sehen Sie alle Ihre Schubladen (wo nist die Anzahl der Schubladen).

set: Stellen Sie sich vor, Sie suchen immer noch nach Ihren Socken in Ihrem Schrank, aber jetzt wissen Sie, in welcher Schublade sich Ihre Socken befinden, beispielsweise in der 3. Schublade. Sie suchen also nur in der 3. Schublade, anstatt in allen Schubladen zu suchen. Das nennen wir O(1), denn im schlimmsten Fall sehen Sie nur in einer Schublade.


3
Die Verwendung von Echtzeitbeispielen ist der beste Weg, um etwas zu verstehen oder zu lehren. Gut gemacht!
Workonphp

@juliomalegria Stellen die Sockenschubladen Elemente in den list/ setoder Speicherplätzen für die Elemente dar?
AlexG

Ist der Grund dafür, dass wir "wissen, dass sich die Socken in der 3. Schublade befinden", dass der zu suchende Wert gehasht wird und wir direkt zum entsprechenden Speicherort gehen können, um nach den Daten zu suchen?
AlexG

Dies ist ein perfekter ELI5 für das Problem!
AK47

1
Was für ein anschauliches, prägnantes Beispiel, um Big-O und den Wert von Hashsets zu veranschaulichen! Ein großes Lob.
kghastie

10

Ich denke, Sie müssen sich ein Buch über Datenstrukturen genauer ansehen. Grundsätzlich werden Python-Listen als dynamische Arrays und Sets als Hash-Tabellen implementiert .

Die Implementierung dieser Datenstrukturen verleiht ihnen radikal unterschiedliche Eigenschaften. Beispielsweise hat eine Hash-Tabelle eine sehr schnelle Suchzeit, kann jedoch die Einfügereihenfolge nicht beibehalten.


Tut mir leid, einen alten Thread wiederzubeleben. Aber irgendwelche Empfehlungen zu einem Buch?
Anakhand

4

list: Stellen Sie sich vor, Sie suchen nach Ihrem Stift, wissen aber nicht, in welcher Schublade sich Ihr Stift befindet. Sie müssen also Schublade für Schublade suchen, bis Sie ihn finden (oder vielleicht nie). Das nennen wir O (n), denn im schlimmsten Fall sehen Sie alle Ihre Schubladen (wobei n die Anzahl der Schubladen ist).

set: Stellen Sie sich vor, Sie suchen immer noch nach Ihrem Stift, aber jetzt wissen Sie, in welcher Schublade sich Ihr Stift befindet, beispielsweise in der 8. Schublade. Sie suchen also nur in der 8. Schublade, anstatt in allen Schubladen zu suchen. Das nennen wir O (1), denn im schlimmsten Fall sehen Sie nur in einer Schublade.

Grundsätzlich werden Python- Listen als dynamic arraysund Sets als implementiert hash tables.



3

Obwohl ich bisher noch keine Leistung in Python gemessen habe, möchte ich dennoch darauf hinweisen, dass Listen oft schneller sind.

Ja, Sie haben O (1) gegen O (n). Aber denken Sie immer daran, dass dies nur Informationen über das asymptotische Verhalten von etwas gibt. Das heißt, wenn Ihr n sehr hoch ist, ist O (1) theoretisch immer schneller. In der Praxis muss n jedoch häufig viel größer sein als Ihr üblicher Datensatz.

Sets sind also nicht schneller als Listen an sich, sondern nur, wenn Sie mit vielen Elementen umgehen müssen.


1

Grundsätzlich hängt es von der Operation ab, die Sie ausführen ...

* Um ein Element hinzuzufügen, muss eine Menge keine Daten verschieben. Sie muss lediglich einen Hash-Wert berechnen und einer Tabelle hinzufügen. Für eine Listeneinfügung müssen möglicherweise Daten verschoben werden.

* Zum Löschen eines Elements muss ein Satz lediglich den Hash-Eintrag aus der Hash-Tabelle entfernen. Für eine Liste müssen möglicherweise Daten verschoben werden (durchschnittlich die Hälfte der Daten).

* Für eine Suche (dh einen In-Operator) - ein Satz muss nur den Hash-Wert des Datenelements berechnen, diesen Hash-Wert in der Hash-Tabelle finden und wenn er vorhanden ist - dann Bingo. Für eine Liste muss die Suche nacheinander nach jedem Element suchen - durchschnittlich 1/2 aller Begriffe in der Liste. Selbst für viele 1000 Artikel ist die Suche nach einem Set viel schneller.


0

Eine Liste muss einzeln durchsucht werden, wobei ein Satz oder ein Wörterbuch einen Index für eine schnellere Suche enthält.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.