Wie pflege ich Wörterbuch in einem Heap in Python?

8

Ich habe ein Wörterbuch wie folgt:

%Vor%

Es ist ein Wörterbuch mit Schlüsseln als Name einer Entität und der Wert ist die Zählung dieser Entität. Ich muss die Top 10 Elemente aus dem Wörterbuch zurückgeben.

Ich kann einen Heap schreiben, um es zu tun, aber ich bin mir nicht sicher, wie man einen Wert für das Key Mapping macht, da bestimmte Werte gleich sind.

Gibt es dafür eine andere Datenstruktur?

    
gizgok 10.02.2013, 06:30
quelle

6 Antworten

11

Mit heapq möchten Sie wahrscheinlich so etwas tun:

%Vor%

Beachten Sie, dass, da heapq nur einen Min-Heap implementiert, es besser ist, die Werte zu invertieren, so dass größere Werte kleiner werden.

Diese Lösung wird bei kleinen Heap-Größen langsamer sein, zum Beispiel:

%Vor%

Bei 3000 Werten ist es nur etwas schneller als die sorted Version, die O(nlogn) anstelle von O(n + mlogn) ist. Wenn wir das dict auf 10000 erhöhen, wird die heapq version noch schneller:

%Vor%

Das Timing hängt wahrscheinlich auch von der Maschine ab, auf der Sie laufen. Sie sollten sich wahrscheinlich überlegen, welche Lösung in Ihrem Fall am besten funktioniert. Wenn die Effizienz nicht kritisch ist, würde ich vorschlagen, die sorted Version zu verwenden, weil es einfacher ist.

    
Bakuriu 10.02.2013, 07:23
quelle
2

Um die ersten 10 Elemente zu erhalten, nehmen wir an, dass die Nummer an zweiter Stelle steht:

%Vor%

Wenn Sie nach Wert sortieren möchten, dann ändern Sie einfach den Schlüssel in key=itemgetter(1,0) .

Wie bei einer Datenstruktur klingt ein Heap so, wie Sie es sich wünschen. Behalte sie einfach als Tupel und vergleiche den Zahlenbegriff.

    
Raufio 10.02.2013 06:54
quelle
1

Wenn das Wörterbuch constant bleibt, versuchen Sie nicht, heapq direkt oder über collections.Counter , können Sie versuchen, die Wörterbuchelemente mit zu sortieren der Wert als Schlüssel in umgekehrter Reihenfolge und dann die ersten 10 Elemente daraus erhalten. Sie müssen das Wörterbuch aus den Tupeln

neu erstellen %Vor%

Wenn Sie heapq verwenden, um den Heap zu erstellen, benötigen Sie nlogn operations, wenn Sie einen Heap erstellen, indem Sie die Elemente einfügen, oder logn , wenn Sie eine Liste heapen, gefolgt von mlogn operations top m elements

Wenn Sie die Elemente sortieren, ist der Python-Sortieralgorithmus im schlimmsten Fall garantiert O(nlogn) (siehe TIM Sort ) und das Holen der ersten 10 Elemente wäre ein konstanter Vorgang

    
Abhijit 10.02.2013 06:50
quelle
0

Bakurius Antwort ist korrekt (benutze heapq.nlargest).

Aber wenn Sie sich für den richtigen Algorithmus interessieren, verwendet quickselect ein ähnliches Prinzip wie Quicksort und wurde von derselben Person erfunden: C.A.R. Hoare.

Es unterscheidet sich jedoch dadurch, dass das Array nicht vollständig sortiert wird: Wenn Sie nach dem Beenden nach den obersten n Elementen gefragt haben, befinden sie sich an den ersten n Positionen im Array, aber nicht unbedingt in sortierter Reihenfolge.

Wie Quicksort beginnt es damit, ein Pivot-Element auszuwählen und das Array so zu drehen, dass alle a [: j] kleiner oder gleich a [j] und alle a [j + 1:] größer als a [j sind ].

Als nächstes, wenn j == n, dann sind die größten Elemente a [: j]. Wenn j & gt; n, dann wird quickselect rekursiv nur für die Elemente aufgerufen, die vom Pivot übrig sind. Und wenn j & lt; Dann wird QuickSelect für die Elemente rechts vom Drehpunkt aufgerufen, um die größten n - j - 1 Elemente aus diesen zu extrahieren.

Da Quickselect rekursiv auf nur einer Seite des Arrays aufgerufen wird (im Gegensatz zu Quicksort, das bei beiden rekursiv aufgerufen wird), arbeitet es in linearer Zeit (wenn die Eingabe zufällig angeordnet ist und es keine wiederholten Schlüssel gibt). Dies hilft auch, den rekursiven Aufruf in eine while-Schleife umzuwandeln.

Hier ist ein Code. Um es zu verstehen, sind die Invarianten in der äußeren while-Schleife, dass die Elemente xs [: lo] garantiert in der Liste von n large sind, und dass die Elemente xs [hi:] garantiert nicht in der n größten sind.

%Vor%     
Paul Hankin 10.02.2013 08:31
quelle
0

Stellen Sie sich ein Diktat vor (Zuordnung von a-z mit a = 1 und z = 26):

%Vor%

Jetzt können Sie das tun:

%Vor%

Sie haben auch angegeben, dass einige Werte des Mappings gleich sind. Jetzt aktualisieren wir d so, dass es die Buchstaben A-Z mit dem Mapping 1-26 hat:

%Vor%

Nun werden sowohl A-Z als auch a-z auf 1-26 :

abgebildet %Vor%

Bei doppelten Zuordnungen ist das einzige sinnvolle Ergebnis das Zurückgeben einer Liste von Schlüsseln mit dem folgenden Wert:

%Vor%

Und Sie könnten heapq hier verwenden:

%Vor%

Sie haben nicht angegeben, was Sie mit den Duplikatergebnissen machen möchten, also nehme ich an, Sie möchten, dass diese Duplikate eliminiert werden, während die Ergebnisliste N lang bleiben soll.

Das macht das:

%Vor%     
dawg 10.02.2013 07:33
quelle
0
___ qstnhdr ___ Wie pflege ich Wörterbuch in einem Heap in Python? ___ answer14795471 ___

Um die ersten 10 Elemente zu erhalten, nehmen wir an, dass die Nummer an zweiter Stelle steht:

%Vor%

Wenn Sie nach Wert sortieren möchten, dann ändern Sie einfach den Schlüssel in %code% .

Wie bei einer Datenstruktur klingt ein Heap so, wie Sie es sich wünschen. Behalte sie einfach als Tupel und vergleiche den Zahlenbegriff.

    
___ qstntxt ___

Ich habe ein Wörterbuch wie folgt:

%Vor%

Es ist ein Wörterbuch mit Schlüsseln als Name einer Entität und der Wert ist die Zählung dieser Entität. Ich muss die Top 10 Elemente aus dem Wörterbuch zurückgeben.

Ich kann einen Heap schreiben, um es zu tun, aber ich bin mir nicht sicher, wie man einen Wert für das Key Mapping macht, da bestimmte Werte gleich sind.

Gibt es dafür eine andere Datenstruktur?

    
___ answer14795447 ___

Wenn das Wörterbuch constant bleibt, versuchen Sie nicht, heapq direkt oder über collections.Counter , können Sie versuchen, die Wörterbuchelemente mit zu sortieren der Wert als Schlüssel in umgekehrter Reihenfolge und dann die ersten 10 Elemente daraus erhalten. Sie müssen das Wörterbuch aus den Tupeln

neu erstellen %Vor%

Wenn Sie heapq verwenden, um den Heap zu erstellen, benötigen Sie %code% operations, wenn Sie einen Heap erstellen, indem Sie die Elemente einfügen, oder %code% , wenn Sie eine Liste heapen, gefolgt von %code% operations top %code% elements

Wenn Sie die Elemente sortieren, ist der Python-Sortieralgorithmus im schlimmsten Fall garantiert %code% (siehe TIM Sort ) und das Holen der ersten 10 Elemente wäre ein konstanter Vorgang

    
___ answer14795642 ___

Mit %code% möchten Sie wahrscheinlich so etwas tun:

%Vor%

Beachten Sie, dass, da %code% nur einen Min-Heap implementiert, es besser ist, die Werte zu invertieren, so dass größere Werte kleiner werden.

Diese Lösung wird bei kleinen Heap-Größen langsamer sein, zum Beispiel:

%Vor%

Bei 3000 Werten ist es nur etwas schneller als die %code% Version, die %code% anstelle von %code% ist. Wenn wir das dict auf 10000 erhöhen, wird die %code% version noch schneller:

%Vor%

Das Timing hängt wahrscheinlich auch von der Maschine ab, auf der Sie laufen. Sie sollten sich wahrscheinlich überlegen, welche Lösung in Ihrem Fall am besten funktioniert. Wenn die Effizienz nicht kritisch ist, würde ich vorschlagen, die %code% Version zu verwenden, weil es einfacher ist.

    
___ answer14795710 ___

Stellen Sie sich ein Diktat vor (Zuordnung von %code% mit a = 1 und z = 26):

%Vor%

Jetzt können Sie das tun:

%Vor%

Sie haben auch angegeben, dass einige Werte des Mappings gleich sind. Jetzt aktualisieren wir %code% so, dass es die Buchstaben %code% mit dem Mapping 1-26 hat:

%Vor%

Nun werden sowohl %code% als auch %code% auf %code% :

abgebildet %Vor%

Bei doppelten Zuordnungen ist das einzige sinnvolle Ergebnis das Zurückgeben einer Liste von Schlüsseln mit dem folgenden Wert:

%Vor%

Und Sie könnten heapq hier verwenden:

%Vor%

Sie haben nicht angegeben, was Sie mit den Duplikatergebnissen machen möchten, also nehme ich an, Sie möchten, dass diese Duplikate eliminiert werden, während die Ergebnisliste N lang bleiben soll.

Das macht das:

%Vor%     
___ answer14796004 ___

Bakurius Antwort ist korrekt (benutze heapq.nlargest).

Aber wenn Sie sich für den richtigen Algorithmus interessieren, verwendet quickselect ein ähnliches Prinzip wie Quicksort und wurde von derselben Person erfunden: C.A.R. Hoare.

Es unterscheidet sich jedoch dadurch, dass das Array nicht vollständig sortiert wird: Wenn Sie nach dem Beenden nach den obersten n Elementen gefragt haben, befinden sie sich an den ersten n Positionen im Array, aber nicht unbedingt in sortierter Reihenfolge.

Wie Quicksort beginnt es damit, ein Pivot-Element auszuwählen und das Array so zu drehen, dass alle a [: j] kleiner oder gleich a [j] und alle a [j + 1:] größer als a [j sind ].

Als nächstes, wenn j == n, dann sind die größten Elemente a [: j]. Wenn j & gt; n, dann wird quickselect rekursiv nur für die Elemente aufgerufen, die vom Pivot übrig sind. Und wenn j & lt; Dann wird QuickSelect für die Elemente rechts vom Drehpunkt aufgerufen, um die größten n - j - 1 Elemente aus diesen zu extrahieren.

Da Quickselect rekursiv auf nur einer Seite des Arrays aufgerufen wird (im Gegensatz zu Quicksort, das bei beiden rekursiv aufgerufen wird), arbeitet es in linearer Zeit (wenn die Eingabe zufällig angeordnet ist und es keine wiederholten Schlüssel gibt). Dies hilft auch, den rekursiven Aufruf in eine while-Schleife umzuwandeln.

Hier ist ein Code. Um es zu verstehen, sind die Invarianten in der äußeren while-Schleife, dass die Elemente xs [: lo] garantiert in der Liste von n large sind, und dass die Elemente xs [hi:] garantiert nicht in der n größten sind.

%Vor%     
___ tag123datastrukturen ___ Eine Datenstruktur ist eine Möglichkeit, Daten so zu organisieren, dass bestimmte Eigenschaften dieser Daten effizient abgefragt und / oder aktualisiert werden können. ___ tag123python ___ Python ist eine dynamische und stark typisierte Programmiersprache, die die Usability betont. Zwei ähnliche, aber größtenteils inkompatible Versionen von Python sind weit verbreitet (2 und 3). Wenn Sie eine versionsspezifische Python-Frage haben, sollten Sie die Tags [python-2.7] oder [python-3.x] zusätzlich zum Tag [python] verwenden. Wenn Sie eine Python-Variante wie jython, pypy, iron-python usw. verwenden, kennzeichnen Sie diese bitte entsprechend. ___ antwort23221627 ___

Wie wäre es mit dem folgenden, es sollte O (len (xs)) sein.

Sie tauschen einfach die ersten n Elemente mit dem größten der verbleibenden Elemente aus.

%Vor%     
___ tag123heap ___ Ein Heap (Datenstruktur) ist ein Baum, der in Bezug auf die Tiefe geordnet ist. Heap kann sich auch auf den Prozessspeicher beziehen, der für die dynamische Zuweisung reserviert ist. ___
user3560727 22.04.2014 13:54
quelle

Tags und Links