2017-02-01 4 views
2

Ich habe eine Textdatei, die ich in einer Liste speichern muss.Dateiinhalt in eine Liste einfügen?

DATEI:

1 1 
4 2 
9 10 

Ich möchte eine Liste von Objekten haben. L = [obj obj obj]

Code:

def putInList(pathToFile): 
    myList = [] 
    with open(pathToFile) as f: 
     for line in f: 
      s = line.split() 
      x, y = [int(v) for v in s] 
      jemand = Mensch(x, y) 
      myList.append(jemand) 
    return myList 

Dies funktioniert gut! Mein Problem ist, dass ich DISK MEMORY die Anzahl der Zeilen mal zugreifen!

Und dieses Beispiel ist künstlich, ich werde mit viel größeren Dateien arbeiten. Also habe ich einen Slicer geschrieben, der sie in ~100MB.txt Dateien steckt. Also würde ich sie gerne in eine list ohne Zugriff auf die disk memory Millionen Male setzen.

Nach Suche und anderen Fragen auf Stackoverflow ich dieses Stück Code gefunden:

a = open(fileToPath, 'r') 
L = [line for line in a.readlines()] 

Aber ich habe keine Ahnung, wie man eine Liste zu analysieren?

+1

Ihre Annahme ist falsch, Sie nicht auf Festplattenspeicher $ Zeilen Zeiten zugreifen. Puffern geht damit um. Keine Sorge, ich habe mehrere Gigabyte große Dateien durchsucht. – L3viathan

+0

@ L3viathan, nur das Parsen einer 100MB Datei dauert 15 Minuten! Klingt das normal? –

+0

Ich weiß nicht was deine 'Mensch' Klasse macht, also weiß ich nicht genau was der Flaschenhals ist. Aber die Aufteilung der Datei in Teile hilft nicht, wenn Sie am Ende sowieso alles in Ihren Arbeitsspeicher legen. Für weitere Vorschläge siehe meine Antwort. – L3viathan

Antwort

2

Ihre Annahme ist falsch, Sie werden nicht auf Festplattenspeicher $ Zeilen Zeiten zugreifen. Puffern geht damit um.

Ich kann jedoch ein paar Empfehlungen machen. Ihre Zeilenaufteilungslogik ist komplizierter als sie sein muss. Eine Möglichkeit, es zu machen (meiner Meinung nach) klarer, tut:

x, y = map(int, line.split()) 

diese Weise können Sie nicht unnötig eine Liste erstellen, die unmittelbar danach verworfen.

Wenn Sie später durch myList laufen, und es nur einmal tun, können Sie die Liste vollständig, Tropfen und eine Generatorfunktion statt:

def putInList(pathToFile): 
    with open(pathToFile) as f: 
     for line in f: 
      x, y = map(int, line.split()) 
      yield Mensch(x, y) 

Sie können es dann iterieren for mensch in putInList(filename): verwenden, obwohl könnte man möchte die Funktion in diesem Fall umbenennen. Wenn Sie noch eine Liste benötigen, würde ich das trotzdem tun und die Liste mit myList = list(putInList(filename)) abrufen.

+0

Ich mache nichts in Mensch für jetzt .. Nur Parsing und Speichern '100MB' Datei in einer Liste von Objekten und es macht mich verrückt, warum es dauert 15-20 Minuten ~. –

+0

Für 10MB ging es von 3 Minuten runter bis 2:30 Uhr also eine kleine Beschleunigung. Ich werde jetzt 'map (int, line.split())' verwenden.Aber ich kann einfach nirgends sehen, wie lange es dauern sollte ... –

+0

Wenn Sie im Durchschnitt zwei 2-stellige Zahlen in einer Zeile haben, sind das 6 Bytes pro Zeile, was etwa 17 Millionen Objekte bedeutet - einschließlich des Overheads für Python-Objekte wird wahrscheinlich zu viel mehr Daten im RAM übersetzen. Ich schrieb die einfachste mögliche 'Mensch'-Klasse, die zu Ihrer Spezifikation passt, und ein Objekt benötigt 32 Bytes im RAM. Das ist schon weit über 500 MB. – L3viathan

0

readLines()returns a list of the lines in Ihrer Textdatei standardmäßig. Also, was ich denke, dass Sie tun sollten, ist:

def putInList(pathToFile): 
    myList = [] 
    fileHandle = open(pathToFile, "r") 
    lines = fileHandle.readLines() 
    for line in lines: 
     values = line.split() 
     x, y = [int(v) for v in values] 
     jemand = Mensch(x, y) 
     myList.append(jemand) 
    return myList