Come leggere un file senza newline?


374

In Python, chiamando

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

risulta in un elenco in cui ogni elemento è una riga nel file. È un po 'stupido ma comunque: readlines()scrive anche un carattere newline per ogni elemento, cosa che non vorrei che accadesse.

Come posso evitarlo?


4
Uso striscia: [l.strip('\n\r') for l in temp]. O addirittura rstrip. E poiché l'iterazione qui può essere in openinvece di in temp.
Gorlum0

11
Sarei bello se in Python 3 ci fosse un valore per impostare l' newlineargomento di open su quelle nuove righe finali traballanti.
jxramos,

Risposte:


555

Puoi leggere l'intero file e dividere le righe usando str.splitlines:

temp = file.read().splitlines()

Oppure puoi rimuovere manualmente la nuova riga:

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

Nota: quest'ultima soluzione funziona solo se il file termina con una nuova riga, altrimenti l'ultima riga perderà un carattere.

Questo assunto è vero nella maggior parte dei casi (in particolare per i file creati da editor di testo, che spesso fanno aggiungere un ritorno a capo termina in ogni caso).

Se vuoi evitare questo, puoi aggiungere una nuova riga alla fine del file:

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]

O un'alternativa più semplice è stripinvece la newline:

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

O addirittura, anche se piuttosto illeggibile:

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

Il che sfrutta il fatto che il valore restituito di ornon è un valore booleano, ma l'oggetto che è stato valutato vero o falso.


Il readlinesmetodo è effettivamente equivalente a:

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

Dal momento che readline()mantiene la newline anche readlines()mantiene.

Nota: per la simmetria per readlines()il writelines()metodo non non aggiunge finire a capo, quindi f2.writelines(f.readlines())produce una copia esatta di fa f2.


1
Si noti che [line.rstrip('\n') for line in file]rimuoverà più di un finale \n.
Wes Turner,

1
Più semplicemente, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]potrebbe invece essere [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner,

10
Queste soluzioni leggono l'intero file in memoria. Cambiare le parentesi quadre di una comprensione di lista in parentesi crea un'espressione di generatore che ti permette di scorrere il file una riga alla volta: for line in (x.strip() for x in f):
Joseph Sheedy,

2
@velotron Non è proprio questo il punto della domanda / risposta. Inoltre: tieni presente che withchiude i file quando termina il blocco, il che significa che non puoi farlo with open(...) as f: lines = (line for line in f)e usarlo linesal di fuori withperché otterrai un errore I / O. Puoi essere pigro usando un genexp, ma devi consumarlo prima di chiudere il file.
Bakuriu,

@WesTurner. Ma non ci sarà più di una nuova riga finale. La nuova riga extra farà parte della prossima riga vuota
Fisico pazzo,

38
temp = open(filename,'r').read().split('\n')

14
Cosa accadrebbe con le \r\nnewline? ;)
Wolph,

26
Python gestisce automaticamente .split('\n')le newline universali, quindi si divide correttamente, indipendentemente dalla convenzione newline. Poco importa se leggi il file in modalità binaria, in questo caso splitlines()gestisce le nuove righe universali mentre split('\n')no.
Bakuriu,

7
E c'è sempre os.linesep:)
askewchan

1
@LarsH, sarebbe utile in alcune circostanze, sul mio sistema le \r\nterminazioni di linea non vengono convertite \n, sia come testo che binario, quindi os.linesepfunzionerebbe dove \nno. Ma splitlinesè chiaramente la scelta migliore, nel caso in cui menzioni dove il file non corrisponde al sistema operativo. Davvero l'ho menzionato per lo più nel caso in cui le persone che guardano questa discussione non fossero a conoscenza della sua esistenza.
askewchan,

1
@askewchan Forse stai utilizzando una versione non aggiornata di Python. Credo che a partire da Python 3, le newline universali siano abilitate di default, cioè \r\nverrebbero convertite in file di testo anche quando si esegue Linux.
Arthur Tacca,

13

un altro esempio:

Lettura del file una riga alla volta. Rimozione di caratteri indesiderati con dall'estremità della stringastr.rstrip(chars)

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

vedi anche str.strip([chars])estr.lstrip([chars])

(python> = 2.0)


10
temp = open(filename,'r').read().splitlines()

5
Sei sicuro che questo chiuda il file? Penso che non lo sia, quindi non è proprio un liner ...
Ray Hulha,

9

Penso che questa sia l'opzione migliore.

temp = [line.strip() for line in file.readlines()]

8
Questa soluzione rimuove anche gli spazi iniziali e finali, che non è previsto.
Roland Illig,

La comprensione è davvero bella, però. Almeno con Python 3, si può usare temp = [line.rstrip() for line in file.readlines()]per ottenere ciò che le note di @Roland_Illig sono destinate.
bballdave025,

Se hai intenzione di iterare su tutte le linee, perché non fare così pigramente? Con .readlines(), stai effettivamente iterando sull'intero file due volte.
AMC,

1

Prova questo:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  

4
Mentre questo frammento di codice può risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Cerca inoltre di non aggiungere il tuo codice a commenti esplicativi, in quanto ciò riduce la leggibilità sia del codice che delle spiegazioni!
Arrivederci StackExchange il

Non vedo perché qualcuno dovrebbe usare questo su alcune delle soluzioni alternative.
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() 

3
Si prega di aggiungere alcune spiegazioni in modo che possano essere utili ad altri.
Samuellawrentz,

È necessario utilizzare un gestore di contesto per gestire l'oggetto file e scorrere direttamente il file. Usando .readlines()così, stai effettivamente iterando sull'intero file due volte.
AMC,

-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])

2
Ma cosa succede se la riga contiene una virgola?
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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.