Ich verarbeite eine CSV-Datei und zähle die eindeutigen Werte von Spalte 4. Bis jetzt habe ich diese drei Wege codiert. Der eine verwendet "if key in dictionary", der zweite den KeyError und der dritte "DefaultDictionary". Zum Beispiel (wo x [3] ist der Wert aus der Datei und "a" ist ein Wörterbuch):
Erster Weg:
%Vor%Zweiter Weg:
%Vor%Dritter Weg:
%Vor%Meine Frage ist: welcher Weg ist effizienter ... sauberer ... besser ... usw. Oder gibt es einen besseren Weg? Beide Wege funktionieren und geben die gleiche Antwort, aber ich dachte, ich würde den Schwarmgeist als einen Lernfall anzapfen.
Danke -
Verwenden Sie collections.Counter
. Counter
ist syntaktischer Zucker für defaultdict(int)
, aber das Beste daran ist, dass es im Konstruktor ein iterables akzeptiert und somit einen zusätzlichen Schritt speichert (ich nehme an, dass alle obigen Beispiele in eine for-Schleife eingeschlossen sind.)
Vor der Einführung von collections.Counter
war collections.defaultdict
das idiomatische für diese Aufgabe, also für Benutzer & lt; 2.7, benutze defaultdict
.
Sie haben gefragt, was effizienter ist. Angenommen, Sie sprechen von Ausführungsgeschwindigkeit: Wenn Ihre Daten klein sind, ist das egal. Wenn es groß und typisch ist, wird der Fall "schon existiert" viel öfter passieren als der Fall "nicht im Diktat". Diese Beobachtung erklärt einige der Ergebnisse.
Im Folgenden finden Sie einen Code, der mit dem Modul timeit
verwendet werden kann, um die Geschwindigkeit ohne Datei-Lese-Overhead zu untersuchen. Ich habe mir die Freiheit genommen, eine fünfte Methode hinzuzufügen, die nicht unkompetent ist und auf jedem Python ab mindestens 1.5.2 (getestet) läuft.
Typischer Lauf (im Fenster "Eingabeaufforderung" von Windows XP):
%Vor%Hier sind die Ergebnisse (ms pro Schleife):
%Vor%Noch ein Timing-Versuch:
%Vor% Die Geschwindigkeit von Counter
ist möglicherweise darauf zurückzuführen, dass sie teilweise in Python-Code implementiert ist, während defaultdict
vollständig in C (mindestens in 2.7) ist.
Beachten Sie, dass Counter()
NICHT nur "syntaktischer Zucker" für defaultdict(int)
ist - es implementiert ein vollständiges Objekt bag
aka multiset
- weitere Informationen finden Sie in den Dokumenten. Sie können Sie davon abhalten, das Rad neu zu erfinden, wenn Sie eine ausgefallene Nachbearbeitung benötigen. Wenn Sie nur Dinge zählen möchten, verwenden Sie defaultdict
.
Update als Antwort auf eine Frage von @Steven Rumbalski: "" "Ich bin gespannt, was passiert, wenn Sie das iterable in den Counter-Konstruktor verschieben: d = Counter (iterable)? Habe Python 2.6 und kann es nicht testen.) "" "
tally6: macht nur d = Count(iterable); return d
, benötigt 60.0 ms
Sie könnten die Quelle (collections.py im SVN-Repository) sehen ... hier ist meine Python27\Lib\collections.py
, wenn iterable
keine Mapping-Instanz ist:
Haben Sie diesen Code schon einmal gesehen? Es gibt eine ganze Menge Carry-On, nur um Code aufzurufen, der in Python 1.5.2 :-O
Da Sie keinen Zugriff auf den Counter haben, ist Ihr dritter Ansatz die beste Wahl. Es ist viel sauberer und einfacher zu lesen. Außerdem hat es nicht die fortwährende Prüfung (und Verzweigung), die die ersten beiden Ansätze haben, was es effizienter macht.
Tags und Links python dictionary unique-key