Wie lese ich eine Datei ohne Zeilenumbrüche?

374

In Python anrufen

temp = open(filename,'r').readlines()

führt zu einer Liste, in der jedes Element eine Zeile in der Datei ist. Es ist ein bisschen dumm, aber trotzdem: readlines()Schreibt auch ein Zeilenumbruchzeichen in jedes Element, was ich nicht möchte.

Wie kann ich das vermeiden?

Yotam
quelle
4
Streifen verwenden : [l.strip('\n\r') for l in temp]. Oder sogar rstrip. Und seit der Iteration hier kann es in openstatt sein in temp.
Gorlum0
11
Ich wäre nett, wenn es in Python 3 einen Wert gäbe, um das newlineArgument von open auf diese verkürzten nachgestellten Zeilenumbrüche zu setzen.
Jxramos

Antworten:

554

Sie können die gesamte Datei und die geteilten Zeilen lesen mit str.splitlines:

temp = file.read().splitlines()

Oder Sie können den Zeilenumbruch von Hand entfernen:

temp = [line[:-1] for line in file]

Hinweis: Diese letzte Lösung funktioniert nur, wenn die Datei mit einem Zeilenumbruch endet. Andernfalls verliert die letzte Zeile ein Zeichen.

Diese Annahme gilt in den meisten Fällen (vor allem für Dateien , die von Text - Editoren erstellt, die oft tun eine Endung Newline hinzufügen sowieso).

Wenn Sie dies vermeiden möchten, können Sie am Ende der Datei eine neue Zeile hinzufügen:

with open(the_file, 'r+') as f:
    f.seek(-1, 2)  # go at the end of the file
    if f.read(1) != '\n':
        # add missing newline if not already present
        f.write('\n')
        f.flush()
        f.seek(0)
    lines = [line[:-1] for line in f]

Oder eine einfachere Alternative ist stripstattdessen die Newline:

[line.rstrip('\n') for line in file]

Oder sogar, obwohl ziemlich unlesbar:

[line[:-(line[-1] == '\n') or len(line)+1] for line in file]

Was die Tatsache ausnutzt, dass der Rückgabewert von orkein Boolescher Wert ist, sondern das Objekt, das als wahr oder falsch bewertet wurde.


Die readlinesMethode entspricht tatsächlich:

def readlines(self):
    lines = []
    for line in iter(self.readline, ''):
        lines.append(line)
    return lines

# or equivalently

def readlines(self):
    lines = []
    while True:
        line = self.readline()
        if not line:
            break
        lines.append(line)
    return lines

Da readline()hält die Newline auch readlines().

Hinweis: für die Symmetrie readlines()der writelines()Methode nicht nicht hinzufügen Zeilenumbrüche am Ende, so f2.writelines(f.readlines())erzeugt eine exakte Kopie fin f2.

Bakuriu
quelle
1
Beachten Sie, dass dadurch [line.rstrip('\n') for line in file]mehr als ein nachfolgendes Zeichen entfernt wird \n.
Wes Turner
1
Einfacher [line[:-(line[-1] == '\n') or len(line)+1] for line in file]könnte stattdessen sein [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner
10
Diese Lösungen lesen die gesamte Datei in den Speicher. Wenn Sie die eckigen Klammern eines Listenverständnisses in Klammern ändern, wird ein Generatorausdruck erstellt, mit dem Sie zeilenweise über die Datei iterieren können: for line in (x.strip() for x in f):
Joseph Sheedy
2
@velotron Das ist nicht wirklich der Punkt der Frage / Antwort. Beachten Sie außerdem, dass withdie Dateien geschlossen werden, wenn der Block beendet wird. Dies bedeutet, dass Sie dies nicht tun with open(...) as f: lines = (line for line in f)und verwenden könnenlines außerhalb vonwith da ein E / A-Fehler auftritt. Sie können mit einem Genexp faul sein, aber Sie müssen es verbrauchen, bevor Sie die Datei schließen.
Bakuriu
@WesTurner. Es wird jedoch nicht mehr als eine nachfolgende Newline geben. Die zusätzliche neue Zeile wird Teil der nächsten leeren Zeile sein
Mad Physicist
38
temp = open(filename,'r').read().split('\n')
vivek
quelle
14
Was würde mit \r\nZeilenumbrüchen passieren ? ;)
Wolph
26
Python verarbeitet universelle Zeilenumbrüche automatisch und .split('\n')wird daher unabhängig von der Zeilenumbruchkonvention korrekt aufgeteilt. Es wäre wichtig, wenn Sie die Datei im Binärmodus lesen. In diesem Fall werden splitlines()universelle Zeilenumbrüche behandelt, während split('\n')dies nicht der Fall ist .
Bakuriu
7
Und es gibt immer os.linesep:)
Askewchan
1
@LarsH, es würde unter bestimmten Umständen helfen, auf meinem System werden \r\nZeilenenden nicht konvertiert \n, ob als Text oder Binär gelesen, also os.linesepwürde funktionieren, wo \nnicht. Aber splitlinesist eindeutig die bessere Wahl, wenn Sie erwähnen, wo die Datei nicht mit dem Betriebssystem übereinstimmt. Wirklich, ich habe es meistens erwähnt, falls die Leute, die sich diese Diskussion ansehen, sich ihrer Existenz nicht bewusst waren.
Askewchan
1
@askewchan Vielleicht verwenden Sie eine veraltete Version von Python. Ich glaube, dass ab Python 3 standardmäßig universelle Zeilenumbrüche aktiviert sind, dh \r\nfür Textdateien konvertiert werden, selbst wenn Sie unter Linux arbeiten.
Arthur Tacca
13

ein anderes Beispiel:

Datei wird zeilenweise gelesen. Entfernen unerwünschter Zeichen mit vom Ende der Zeichenfolgestr.rstrip(chars)

with open(filename, 'r') as fileobj:
    for row in fileobj:
        print( row.rstrip('\n') )

siehe auch str.strip([chars]) undstr.lstrip([chars])

(Python> = 2,0)

O-9
quelle
10
temp = open(filename,'r').read().splitlines()
Marcel
quelle
5
Sind Sie sicher, dass dies die Datei schließt? Ich denke, dass dies nicht der Fall ist, also ist es nicht wirklich ein
Einzeiler
9

Ich denke, das ist die beste Option.

temp = [line.strip() for line in file.readlines()]
RENZO
quelle
8
Diese Lösung entfernt auch führende und nachfolgende Leerzeichen, was nicht beabsichtigt ist.
Roland Illig
Das Verständnis ist allerdings sehr schön. Zumindest mit Python 3 kann man verwenden temp = [line.rstrip() for line in file.readlines()], um zu ermitteln, was @ Roland_Illig-Notizen beabsichtigt sind.
bballdave025
Wenn Sie alle Zeilen durchlaufen, warum nicht so faul? Mit .readlines()iterieren Sie effektiv zweimal über die gesamte Datei.
AMC
1

Versuche dies:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
Nitesh Soni
quelle
4
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen, da dies die Lesbarkeit sowohl des Codes als auch der Erklärungen beeinträchtigt!
Auf Wiedersehen StackExchange
Ich verstehe nicht, warum jemand dies für einige der alternativen Lösungen verwenden sollte.
AMC
-1
my_file = open("first_file.txt", "r")
for line in my_file.readlines():
    if line[-1:] == "\n":
        print(line[:-1])
    else:
        print(line)
my_file.close() 
Necriss
quelle
3
Bitte fügen Sie einige Erklärungen hinzu, damit sie für andere nützlich sind.
Samuellawrentz
Sie sollten einen Kontextmanager verwenden, um das Dateiobjekt zu verarbeiten, und die Datei direkt durchlaufen. Auf .readlines()diese Weise iterieren Sie effektiv zweimal über die gesamte Datei.
AMC
-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
quelle
2
Aber was ist, wenn die Zeile ein Komma enthält?
Gilch
-8
def getText():
    file=open("ex1.txt","r");

    names=file.read().split("\n");
    for x,word in enumerate(names):
        if(len(word)>=20):
            return 0;
            print "length of ",word,"is over 20"
            break;
        if(x==20):
            return 0;
            break;
    else:
        return names;


def show(names):
    for word in names:
        len_set=len(set(word))
        print word," ",len_set


for i in range(1):

    names=getText();
    if(names!=0):
        show(names);
    else:
        break;
user4730171
quelle