Python-Klasse zum Zusammenführen von sortierten Dateien, wie kann dies verbessert werden?

8

Hintergrund:

Ich bereite große (nicht speicherbare) tabstoppgetrennte Dateien. Während ich die Eingabedatei säubere, baue ich eine Liste im Speicher auf; wenn es zu 1.000.000 Einträgen (ungefähr 1 GB im Speicher) kommt, sortiere ich es (mit dem Standardschlüssel unten) und schreibe die Liste in eine Datei. Diese Klasse dient zum Zurücksetzen der sortierten Dateien. Es funktioniert mit den Dateien, die ich bisher gefunden habe. Mein bisher größter Fall ist das Zusammenführen von 66 sortierten Dateien.

Fragen:

  1. Gibt es Löcher in meiner Logik (wo ist es fragil)?
  2. Habe ich den Merge-Sort implementiert Algorithmus richtig?
  3. Gibt es irgendwelche offensichtlichen Verbesserungen? das könnte gemacht werden?

Beispieldaten:

Dies ist eine Abstraktion einer Zeile in einer dieser Dateien:

'hash_of_SomeStringId\tSome String Id\t\t\twww.somelink.com\t\tOtherData\t\n'

Zum Mitnehmen verwende ich 'SomeStringId'.lower().replace(' ', '') als Sortierschlüssel.

Originalcode:

%Vor%

Bearbeiten: Umsetzung der Vorschläge von Brian Ich habe folgende Lösung gefunden:

Second Edit: Der Code wurde für John Machins Vorschlag aktualisiert:

%Vor%

Grober Test

Verwenden der gleichen Eingabedateien (2,2 GB Daten):

tgray 16.06.2009, 13:42
quelle

2 Antworten

16

Beachten Sie, dass heapq in python2.6 eine neue Funktion merge hat, die dies tut für dich.

Um die benutzerdefinierte Schlüsselfunktion zu handhaben, können Sie den Dateiiterator einfach mit etwas umhüllen, das ihn so schmückt, dass er auf der Basis des Schlüssels vergleicht, und ihn anschließend aus dem Text entfernen:

%Vor%

[Bearbeiten] Selbst in früheren Versionen von Python lohnt es sich, einfach die Implementierung von merge vom späteren heapq-Modul zu übernehmen. Es ist reines Python und läuft unverändert in python2.5, und da es einen Heap verwendet, um das nächste Minimum zu bekommen, sollte es sehr effizient sein, wenn man eine große Anzahl von Dateien zusammenführt.

Sie sollten einfach heapq.py von einer python2.6-Installation kopieren können, kopieren Sie es als "heapq26.py" in Ihre Quelle und verwenden Sie " from heapq26 import merge " - es werden keine 2.6 spezifischen Funktionen verwendet. Alternativ können Sie auch einfach die Zusammenführungsfunktion kopieren (die Heappop-Aufrufe werden neu geschrieben, um auf das heapq-Modul python2.5 zu verweisen).

    
Brian 16.06.2009, 13:50
quelle
2

& lt; & lt; Diese "Antwort" ist ein Kommentar zu dem resultierenden Code des ursprünglichen Fragestellers & gt; & gt;

Vorschlag: Die Verwendung von eval () ist ummmm und was Sie tun, beschränkt den Aufrufer auf die Verwendung von Lambda - Schlüsselextraktion kann mehr als einen Einzeiler erfordern, und in jedem Fall brauchen Sie nicht die gleiche Funktion für die Vorstufe Sortierschritt?

Also ersetzen Sie das:

%Vor%

mit diesem:

%Vor%     
John Machin 17.06.2009 00:33
quelle