2008-12-04 8 views
26

Wenn Zeilen aus einer Textdatei mit Python zu lesen, das End-Linie Zeichen oft abgeschnitten werden muss, bevor die Textverarbeitung, wie im folgende Beispiel:End-line Zeichen aus den Zeilen lesen aus Textdatei, mit Python

f = open("myFile.txt", "r") 
    for line in f: 
     line = line[:-1] 
     # do something with line 

Gibt es eine elegante Möglichkeit oder ein Idiom zum Abrufen von Textzeilen ohne das Endzeilenzeichen?

Antwort

44

Die idiomatische Weg, dies in Python zu tun ist, rstrip ('\ n') zu verwenden: hat

for line in open('myfile.txt'): # opened in text-mode; all EOLs are converted to '\n' 
    line = line.rstrip('\n') 
    process(line) 

Jede der anderen Alternativen eine Gotcha:

  • Datei ('...') .read(). splitlines() muss die gesamte Datei gleichzeitig in den Speicher laden.
  • Zeile = Zeile [: - 1] schlägt fehl, wenn die letzte Zeile kein EOL hat.
+15

HTTP und andere Protokolle angeben '\ r \ n' für Zeilenenden, Sie sollten daher line.rstrip ('\ r \ n') für Robustheit verwenden. –

+0

Danke für Ihre Hilfe! Ich musste eine Textdatei öffnen und ich war erstaunt zu sehen, dass das \ n-Ding sogar in Python ist, wie es in Perl, C und vielen anderen Sprachen ist. Ich werde das Lesezeichen setzen und es nie vergessen. – bjd2385

5

Was ist falsch an Ihrem Code? Ich finde es sehr elegant und einfach. Das einzige Problem ist, dass, wenn die Datei nicht in einem Zeilenumbruch endet, die letzte zurückgegebene Zeile kein '\n' als das letzte Zeichen hat und daher line = line[:-1] das letzte Zeichen der Zeile falsch abziehen würde.

Der eleganteste Weg, um dieses Problem zu lösen wäre, einen Generator zu definieren, welche die Zeilen der Datei genommen und entfernt das letzte Zeichen aus jeder Zeile nur, wenn das Zeichen ein Newline ist:

def strip_trailing_newlines(file): 
    for line in file: 
     if line[-1] == '\n': 
      yield line[:-1] 
     else: 
      yield line 

f = open("myFile.txt", "r") 
for line in strip_trailing_newlines(f): 
    # do something with line 
+3

Mac-Dateien mit '\ r', Fenster verwendet '\ r \ n', beginnt es klobig zu bekommen. Viel besser zu verwenden str.rstrip() –

+2

Wenn die Datei im Textmodus geöffnet wird, werden die nativen Zeilenenden der Plattform beim Einlesen automatisch in ein einziges '\ n' umgewandelt. Und nur _really old_ Mac OSs verwenden plain '\ r '. Sie können rstrip() nicht verwenden, wenn Sie nachgestellte Leerzeichen und Tabulatoren beibehalten möchten. –

+0

Gute Idee, mit dem Generator. Wäre nützlich in einer wiederverwendbaren Bibliothek. Ich würde Ihre Lösung mit der Lösung von efonitis kombinieren (um das if: else zu retten). Ohne die wiederverwendbare Bibliothek würde ich die Lösung von efotinis bevorzugen (mit line.rstrip ('\ n')). – pythonquick

17

Einfach. Verwenden Sie Teilungslinien()

L = open("myFile.txt", "r").read().splitlines(); 
for line in L: 
    process(line) # this 'line' will not have '\n' character at the end 
+4

Beachten Sie jedoch, dass zuerst die gesamte Datei in den Speicher geladen wird, was sie für einige Situationen möglicherweise ungeeignet macht. –

+0

@Matthew: Ja, du hast Recht. –

+1

macht es genau richtig für mich, danke –

2

Sie auch prüfen, können unter Verwendung von line.rstrip(), um die Leerzeichen am Ende der Linie zu entfernen.

+0

Ich benutze auch rstrip(), aber Sie müssen daran denken, es auch nachstehende Leerzeichen und Tabs entfernt –

+0

Wie efotinis gezeigt hat, können Sie angeben, wenn Sie das Argument chars angeben ausziehen. Aus der Dokumentation: "" "rstrip ([chars]) Das chars-Argument ist eine Zeichenfolge, die die Menge der zu entfernenden Zeichen angibt. Wenn sie weggelassen oder None ist, löscht das chars-Argument standardmäßig Leerzeichen." "" – monkut

3

Vor langer Zeit gab es Liebe, sauber, alt, BASIC-Code, der auf 16 kb Kernmaschinen laufen konnte: wie folgt aus:

if (not open(1,"file.txt")) error "Could not open 'file.txt' for reading" 
while(not eof(1)) 
    line input #1 a$ 
    print a$ 
wend 
close 

nun eine Datei Zeile für Zeile zu lesen, mit weit bessere Hardware und Software (Python), müssen wir das Rad neu zu erfinden:

def line_input (file): 
    for line in file: 
     if line[-1] == '\n': 
      yield line[:-1] 
     else: 
      yield line 

f = open("myFile.txt", "r") 
for line_input(f): 
    # do something with line 

ich bin zu denken, induziert, dass etwas falsch irgendwo gegangen ist ...

+1

Während ich der Meinung bin, dass Python unsere beste Option für eine interpretierte Sprache auf Einstiegsebene ist, stimme ich diesem Kommentar zu, es könnte praktisch sein zu bemerken, dass 16kb BASIC mit einem WHILE-Satz nie üblich waren. – arivero

3

Was haben Sie an diesem Ansatz?

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

Generator Ausdruck vermeidet ganze Datei in den Speicher geladen und with sorgt für Schließen der Datei

Verwandte Themen