effiziente Möglichkeit, das Element in einem Wörterbuch in Python mit einer Schleife zu zählen

7

Ich habe eine Liste von Werten. Ich möchte während einer Schleife die Anzahl der Elemente für jede Klasse (d. H. 1,2,3,4,5)

zählen %Vor%

Ich möchte dieses Ergebnis erhalten

%Vor%     
Gianni Spear 20.08.2013, 19:28
quelle

5 Antworten

13

Für Ihr kleineres Beispiel mit einer begrenzten Anzahl von Elementen können Sie ein Set und ein Diktatverständnis verwenden:

%Vor%

Um es aufzulösen, macht set(mylist) die Liste unifiziert und macht sie kompakter:

%Vor%

Dann durchläuft das Wörterbuchverständnis die eindeutigen Werte und setzt die Zählung aus der Liste.

Dies ist auch wesentlich schneller als mit Counter und schneller als mit setdefault:

%Vor%

Auf meinem Rechner, der druckt (Python 3):

%Vor%

Bei größeren Listen, z. B. 10 Millionen Ganzzahlen mit verschiedenen Elementen (1.500 zufällige Ints), verwenden Sie defaultdict oder fromkeys in einer Schleife:

%Vor%

Drucke:

%Vor%

Sie können sehen, dass Lösungen, die sich in count mit einer moderaten Anzahl von Malen über die große Liste weiterleiten, im Vergleich zu anderen Lösungen schlecht / katastrophal leiden.

    
user688635 20.08.2013, 23:28
quelle
6

Versuchen Sie collections.Counter :

%Vor%

In Ihrem Code können Sie mydict durch Counter ersetzen und

schreiben %Vor%

statt

%Vor%     
Benjamin Peterson 20.08.2013 19:30
quelle
4

Eine Variation des setdefault -Ansatzes ist collections.defaultdict . Das ist ein bisschen schneller.

%Vor%

itertools.groupBy bietet eine weitere Option. Die Geschwindigkeit ist ungefähr gleich Counter (mindestens 2.7)

%Vor%

Allerdings sind die Zeittests auf dieser kleinen Testliste möglicherweise nicht gleich, wenn es um die 32 Gb Daten geht, die das OP in einem Kommentar erwähnt.

Ich habe mehrere dieser Optionen im Wortzählungsfall in python top N Wortzählung, warum Multiprozess langsamer als Einzelprozess

Dort verwendete das OP Counter und versuchte, die Dinge durch Multiprocessing zu beschleunigen. Bei einer 1.2MB-Textdatei war der Zähler, der defaultdict verwendete, schnell und benötigte 0.2 Sekunden. Das Sortieren der Ausgabe, um die oberen 40 Wörter zu erhalten, dauerte so lange wie das Zählen selbst.

Counter war etwas langsamer bei 3.2 und sehr viel langsamer bei 2.7 . Das liegt daran, dass 3.2 eine kompilierte Version ( .so file) ist.

Aber der Zähler, der mylist.count verwendet, bleibt bei der Verarbeitung einer großen Liste stehen; fast 200 Sekunden Es muss diese große Liste mehrmals durchsuchen, einmal um Schlüssel zu sammeln und dann einmal für jeden Schlüssel, wenn es zählt.

    
hpaulj 21.08.2013 05:17
quelle
3

Um den Code zu korrigieren:

%Vor%

sollte sein:

%Vor%     
Grijesh Chauhan 20.08.2013 19:30
quelle
1

Ihr Code weist 1 als Wert für jeden Schlüssel zu. Ersetzen Sie mydict[index] = +1 durch mylist.count(index)

Das sollte funktionieren:

%Vor%     
Animal Spirits 20.08.2013 20:49
quelle