2012-06-20 13 views
5

Ich baue eine Klasse mit ua einem Wörterbuch mit ganzzahligen Schlüsseln und Listenwerten. Das Hinzufügen von Werten zu diesem Wörterbuch scheint jedoch ein echter Flaschenhals zu sein und ich frage mich, ob es eine Möglichkeit geben könnte, meinen Code zu beschleunigen.Python: Optimaler Weg zum Wörterbuch mit Listenwerten

class myClass(): 

    def __init__(self): 
    self.d = defaultdict(list) 

    def addValue(self, index, value): 
    self.d[index].append(value) 

Ist das wirklich der optimale Weg? Ich interessiere mich nicht wirklich für die Reihenfolge der Werte, also gibt es vielleicht eine geeignetere Datenstruktur mit einem schnelleren Anhang. Andererseits scheint "append" nicht das Hauptproblem zu sein, denn wenn ich einfach an eine leere Liste angehängt habe, ist der Code viel schneller. Ich denke, dass das Laden der zuvor gespeicherten Liste die meiste Zeit in Anspruch nimmt?


Ich fand heraus, dass das Problem nicht in der dict ist, aber in der Liste append (obwohl ich sonst in meiner ursprünglichen Post behauptete, für die ich entschuldige ich). Dieses Problem ist auf einen Fehler in Pythons Garbage Collector zurückzuführen, der ausführlich unter this other question erläutert wird. Das Deaktivieren des GC vor dem Hinzufügen aller Werte und das anschließende erneute Aktivieren beschleunigen den Prozess immens!

+2

Das Hinzufügen von Elementen zu einer Liste und das Abrufen von Werten von einem Objekt oder einem Diktat dauert keine Zeit. Um ein Programm zu beschleunigen, finden Sie den Engpass durch Profiling, nicht durch zufällige Code-Änderung. –

+0

Ist die Zuordnung von Elementen zu vorhandenen Schlüsseln wesentlich schneller als das Hinzufügen von Werten zu neuen Schlüsseln? –

+0

Ich habe gerade herausgefunden, dass das Problem nicht im Diktat liegt, sondern in der Liste anhängen (obwohl ich in meinem ursprünglichen Beitrag etwas anderes behauptet habe, wofür ich mich entschuldige). Dann fand ich die Antwort auf meine Frage auf http://stackoverflow.com/questions/2473783/is-there-a-way-to-circumvent-python-list-append-becoming-progressive-slower. Da ich neu auf dieser Seite bin, weiß ich nicht, was das Standardverfahren in diesem Fall ist: Soll ich meinen ursprünglichen Beitrag entfernen? Oder fügen Sie die obigen Details hinzu und antworten Sie auf den Beitrag? – niefpaarschoenen

Antwort

0

Als Schlussfolgerung kann ich sagen, dass mein Code in der ursprünglichen Frage schneller ist als oder so schnell wie alle anderen Vorschläge.

2

Vergleichen es dazu:

class myClass(): 

    def __init__(self): 
    self.d = {} 

    def addValue(self, index, value): 
    self.d.setdefault(index, []).append(value) 
+1

Aus Neugier, warum ist das schneller? Ich hätte gedacht, dass 'defaultdict' hinter den Kulissen etwas sehr ähnliches macht. –

+1

Nach einem kurzen Test fand ich heraus, dass dies nicht schneller ist. Ich mag es einfach besser. – eumiro

+0

Ich denke, hinter den Kulissen tut es das Gleiche; Timings sind auf jeden Fall ähnlich ... Ich bevorzuge jedoch das Defaultdict, weil man im Allgemeinen weniger tippen muss. – niefpaarschoenen

1

Sie sagen, "Better um Vergebung zu bitten, als um Erlaubnis.". Jetzt fragen Sie nicht persönlich um Erlaubnis, aber ich dachte, vielleicht defaultdict tut, und das ist, was es verlangsamt.

try dies:

class myClass(): 

    def __init__(self): 
    self.d = {} 

    def addValue(self, index, value): 
    try: 
     self.d[index].append(value) 
    except KeyError: 
     self.d[index] = [value] 

Dieser versucht, die index Schlüssel im Wörterbuch zugreifen zu können, wenn es nicht vorhanden ist es ein KeyError erhöhen wird, und wirkt auf sie.

Ist es schneller?

+0

Ich habe versucht, Ihren Code und Code von der Frage zu vergleichen (mit [timeit] (http://docs.python.org/library/timeit.html)). Ich habe diesen Test verwendet: 'my = myClass() mein.addValue (3," ab ") mein.addValue (3," cd ") mein.addValue (4," ef ") my.addValue (4, "gh") 'Und der ursprüngliche Code ist schneller! Auf meinem Computer 24.66 usec für Ihren Code und 18.10 usec für Code aus Frage. Sieht so aus, als ob dieser Ansatz nicht die Antwort ist. – stalk

+1

Scheint, dass du dann die schnellste Lösung hast :) – jadkik94

Verwandte Themen