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%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:
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.
Versuchen Sie collections.Counter
:
In Ihrem Code können Sie mydict
durch Counter
ersetzen und
statt
%Vor% Eine Variation des setdefault
-Ansatzes ist collections.defaultdict
. Das ist ein bisschen schneller.
itertools.groupBy
bietet eine weitere Option. Die Geschwindigkeit ist ungefähr gleich Counter
(mindestens 2.7)
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.
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%Tags und Links python performance dictionary coding-style