große Text-Datei einlesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mikue
User
Beiträge: 1
Registriert: Dienstag 13. Februar 2018, 08:39

Dienstag 13. Februar 2018, 08:45

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
Sirius3
User
Beiträge: 8270
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 13. Februar 2018, 09:52

@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?
Benutzeravatar
DeaD_EyE
User
Beiträge: 207
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Dienstag 13. Februar 2018, 10:29

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.
sourceserver.info - sourceserver.info/wiki/ - Support für HL2-Server
narpfel
User
Beiträge: 225
Registriert: Freitag 20. Oktober 2017, 16:10

Dienstag 13. Februar 2018, 11:14

@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.
Antworten