Seite 1 von 1

große Text-Datei einlesen

Verfasst: Dienstag 13. Februar 2018, 08:45
von mikue
Hallo,

ich habe eine Datei mit 258000 Zeilen, die jeweils ein Wort enthalten (ein Wörterbuch). Jetzt möchte ich dieses gerne in eine Liste schreiben mit

Code: Alles auswählen

def lies_woerterbuch(datei):
    file = open(datei,"r")
    liste = []
    for zeile in file:
        zeile = zeile[0:len(zeile)-1] # letztes Zeichen (Umbruch) löschen
        liste.append(zeile)
    file.close()
    return liste
Mit kleinen Dateien funktioniert das super, aber bei großen Dateien arbeitet Python ewig, bis ich es irgendwann abbreche. Das Verrückte ist, dass dieselbe Funktion mit derselben Datei schon mal gut geklappt hat. Und sooo groß ist die ja nun auch nicht (3,2 MB). Aber nun geht es auf zwei Systemen nicht mehr in endlicher Zeit.

Was mache ich falsch?

Micha

Re: große Text-Datei einlesen

Verfasst: Dienstag 13. Februar 2018, 09:52
von Sirius3
@mikue: statt mit len, kann man auch mit negativen Indizes vom Ende her indizieren: `zeile[:-1]`. Üblicherweise nimmt man aber `zeile.rstrip()` oder `zeile.strip()` um überflüssige unsichtbare Zeichen zu entfernen. Öffne eine Datei mit dem with-Statement, dann wird sie auch automatisch geschlossen:

Code: Alles auswählen

def lies_woerterbuch(datei):
    with open(datei) as lines:
        return [line.strip() for line in lines]
Warum die Funktion so lange braucht, kann man leider nicht beantworten, weil das eigentlich nicht sein sollte. Du machst alles richtig. An welcher Stelle bricht das Programm ab, wenn Du es abbrichst? Wie sieht der Stacktrace aus? Ist es wirklich die Funktion, oder hängt das Programm an einer anderen Stelle?

Re: große Text-Datei einlesen

Verfasst: Dienstag 13. Februar 2018, 10:29
von DeaD_EyE

Code: Alles auswählen

def woerterbuch2list(datei):
    with open(datei,"r") as fd:
        return [line.rstrip() for line in fd]

def woerterbuch_gen(datei):
    with open(datei,"r") as fd:
        for line in fd:
            yield line.rstrip()


%timeit woerterbuch2list('datei')
%timeit list(woerterbuch_gen('datei'))
%timeit tuple(woerterbuch_gen('datei'))
%timeit set(woerterbuch_gen('datei'))
Probiere mal den Code. Mit %timeit kannst du in IPython die Zeit messen, die eine Funktion benötigt um ausgeführt zu werden.
Falls du kein IPython hast, auf jeden Fall installieren.

Re: große Text-Datei einlesen

Verfasst: Dienstag 13. Februar 2018, 11:14
von narpfel
@DeaD_EyE: Laufzeit sollte nicht das primäre Entscheidungskriterium sein, sich für oder gegen eine Implementierung zu entscheiden. Zuerst sollte der Code lesbar sein und die richtige Semantik haben. Das ist bei dir nicht gegeben: Tupel sind nicht für homogene Daten gedacht und Sets sind ungeordnet. Es kann sein, dass mikue ein `set` möchte, aber ohne sein Programm zu kennen, können wir nur raten. Und ob sein Code wirklich zu langsam ist, ist auch fraglich, weil ein Dateieinlesen nicht manchmal und zufällig viel langsamer wird.

`fd` ist ein komischer Name für ein Dateiobjekt. Wenn man nichts genaueres über die Datei weiß, als dass sie aus Zeilen besteht, bietet sich `lines` an. `"r"` ist der Standardmodus, muss also nicht angegeben werden.