Beste Methode zum Lesen von durch Zeilenumbrüche getrennten Dateien und zum Verwerfen der Zeilenumbrüche?

83

Ich versuche herauszufinden, wie ich Zeilenumbrüche beim Einlesen von durch Zeilenumbrüche getrennten Dateien in Python am besten beseitigen kann.

Was ich mir ausgedacht habe, ist der folgende Code, einschließlich Wegwerfcode zum Testen.

import os

def getfile(filename,results):
   f = open(filename)
   filecontents = f.readlines()
   for line in filecontents:
     foo = line.strip('\n')
     results.append(foo)
   return results

blahblah = []

getfile('/tmp/foo',blahblah)

for x in blahblah:
    print x

Vorschläge?

Solarce
quelle
Was ist mit Split ("/ n")?
Jle
1
Gleich wie: stackoverflow.com/questions/339537/…
Vijay Dev
Ich denke, es wäre besser, die Datei auch zu schließen
Paweł Prażak

Antworten:

195
lines = open(filename).read().splitlines()
Curt Hagenlocher
quelle
Diese Antwort macht das, was ich wollte. Ich bin sicher, ich muss einige Fehlerprüfungen und ähnliches hinzufügen, aber für diese spezielle Anforderung ist es großartig. Vielen Dank für die Antworten!
Solarce
Ich mag das, aber wie schließt man die Datei, wenn man das Dateihandle nicht speichert? Oder wird es automatisch geschlossen?
IJ Kennedy
6
Mit CPython wird der Referenzzähler für das Dateiobjekt auf Null gesetzt, sobald es nicht mehr verwendet wird, und die Datei wird automatisch geschlossen. Bei rein GC-basierten Implementierungen wie Jython und IronPython wird die Datei möglicherweise erst geschlossen, wenn der GC ausgeführt wird. Daher ist diese knappe Variante möglicherweise nicht optimal.
Curt Hagenlocher
2
Unter Mac OS X 10.7.5 mit 8 GB RAM kann ich Dateien mit bis zu 2047 MB ​​lesen (meine Definition: 1 MB = 1024 x 1024 Byte). 2048 MB lösen eine MemoryError-Ausnahme aus.
Hai Vu
1
@WKPlus Ausgezeichnete Frage - Die Antwort lautet "es kommt darauf an" stackoverflow.com/a/15099341/994153 (CPython schließt es, da der Referenzzähler auf Null fällt, aber andere Python-Implementierungen schließen es möglicherweise nicht, also machen Sie es am besten explizit )
Colin D Bennett
23

Hier ist ein Generator, der das tut, was Sie angefordert haben. In diesem Fall ist die Verwendung von rstrip ausreichend und etwas schneller als der von strip.

lines = (line.rstrip('\n') for line in open(filename))

Wahrscheinlich möchten Sie dies jedoch auch verwenden, um nachgestellte Leerzeichen zu entfernen.

lines = (line.rstrip() for line in open(filename))
TimoLinna
quelle
Sollte es nicht [] um die RHS sein, nicht ()?
Andrew
8
@andrewb Using () gibt einen Generatorausdruck, der nicht so viel Speicher verbraucht wie using [] (ein Listenverständnis.)
Jonathan Hartley
9

Was denkst du über diesen Ansatz?

with open(filename) as data:
    datalines = (line.rstrip('\r\n') for line in data)
    for line in datalines:
        ...do something awesome...

Der Generatorausdruck vermeidet das Laden der gesamten Datei in den Speicher und withstellt das Schließen der Datei sicher

Paweł Prażak
quelle
Dies ist im Wesentlichen die gleiche wie @ TimoLinnas Antwort Jahre zuvor veröffentlicht ...
Martineau
8
for line in file('/tmp/foo'):
    print line.strip('\n')
David Z.
quelle
4

Verwenden Sie einfach Generatorausdrücke:

blahblah = (l.rstrip() for l in open(filename))
for x in blahblah:
    print x

Außerdem möchte ich Ihnen davon abraten, die gesamte Datei im Speicher zu lesen. Das Schleifen über Generatoren ist bei großen Datenmengen viel effizienter.


quelle
3

ich benutze das

def cleaned( aFile ):
    for line in aFile:
        yield line.strip()

Dann kann ich so etwas machen.

lines = list( cleaned( open("file","r") ) )

Oder ich kann bereinigt mit zusätzlichen Funktionen erweitern, um beispielsweise Leerzeilen zu löschen oder Kommentarzeilen oder was auch immer zu überspringen.

S.Lott
quelle
2

Ich würde es so machen:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l
S.Lott
quelle
Während die Antwort von Curt Hagenlocher technisch besser ist, ist diese Antwort ein guter Ausgangspunkt, wenn Sie jeder Zeile eine andere Verarbeitung hinzufügen müssen.
TomOnTime
... if l.strip() is not ''Ich bin mir nicht sicher, ob es beabsichtigt war, Leerzeilen zu filtern, aber dies ist prägnanter als das, was ich in meinem Fall brauche.
Zach Young