2012-09-08 14 views
192

In Python, chiamandoLa lettura di un file senza ritorni a capo

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

risultati in una lista in cui ogni elemento è una riga nel file. È un po 'stupido, ma: readlines() scrive anche carattere di fine riga per ogni elemento, qualcosa che non desidero accadere. Come posso evitarlo?

+2

Uso striscia: '[l.strip ('\ n \ r') per l temp]'. O anche 'rstrip'. E poiché l'iterazione qui può essere 'in open' invece di' in temp'. – gorlum0

+13

Questa domanda è responsabile per ogni punteggio di reputazione che ho – Yotam

+3

Sarebbe bello se in Python 3 esistesse un valore per impostare l'argomento 'newline 'di open su quelle nuove di fine squarcio. – jxramos

risposta

276

È possibile leggere le intere linee di file e split con str.splitlines:

temp = file.read().splitlines() 

Oppure si può spogliare il ritorno a capo a mano:

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

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

Questa ipotesi è vera nella maggior parte dei casi (in particolare per i file creati da editor di testo, che spesso do aggiungono comunque una nuova riga finale).

Se si vuole evitare questo si può 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 è quello di strip il ritorno a capo invece:

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

O ancora, anche se piuttosto illeggibile:

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

Che sfrutta il fatto che il ritorno va il valore di or non è un valore booleano, ma l'oggetto che è stato valutato vero o falso.


Procedimento readlines è in realtà equivale 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 

Poiché readline() mantiene la nuova riga anche readlines() mantiene.

Nota: per simmetria readlines() metodo writelines() non non aggiungere nuove righe termina, così f2.writelines(f.readlines()) produce una copia esatta del f in f2.

+0

Nota che '' [line.rstrip ('\ n') per la riga nel file] '' rimuoverà più di un '' \ n'' finale. –

+0

Più semplicemente, '' [line [:-(line [-1] == '\ n') o len (line) +1] per line in file] '' potrebbe invece essere '' [line [:-(line [-1] == '\ n') o None] per riga nel file] ''. –

+0

Queste soluzioni leggono l'intero file in memoria. Cambiare le parentesi quadre di una comprensione di lista in parentesi fa un'espressione di generatore che ti permette di scorrere il file una riga alla volta: 'per la riga in (x.strip() per x in f):' – velotron

19
temp = open(filename,'r').read().split('\n') 
+8

Cosa succederebbe con le newline '\ r \ n'? ;) – Wolph

+0

@WoLpH Sì, non ho preso in considerazione le newline specifiche della piattaforma. Darà la cosa sbagliata. – vivek

+11

Python gestisce automaticamente i newline universali, quindi '.split ('\ n')' verrà diviso correttamente, indipendentemente dalla convenzione newline. Sarebbe importante se leggeste il file in modalità binaria. In questo caso 'splitlines()' gestisce i newline universali mentre 'split ('\ n')' non lo fa. – Bakuriu

-2
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; 
1
import csv 

with open(filename) as f: 
    csvreader = csv.reader(f) 
    for line in csvreader: 
     print(line[0]) 
2
temp = open(filename,'r').read().splitlines() 
0

Prova questo:

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

Sebbene questo snippet di codice possa risolvere la domanda, [includendo una spiegazione] (// meta.stackexchange.com/questions/114762/explaining-entely-code-based-answers) aiuta davvero a migliorare la qualità del post. Ricorda che stai rispondendo alla domanda per i lettori in futuro, e queste persone potrebbero non conoscere le ragioni del tuo suggerimento sul codice. Cerca anche di non affollare il tuo codice con commenti esplicativi, in quanto ciò riduce la leggibilità sia del codice che delle spiegazioni! – FrankerZ

Problemi correlati