Il metodo migliore per leggere i file delimitati da newline e scartare i newline?


84

Sto cercando di determinare il modo migliore per gestire l'eliminazione dei newline durante la lettura di file delimitati da newline in Python.

Quello che ho trovato è il seguente codice, includi codice usa e getta da testare.

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

Suggerimenti?


che dire dell'utilizzo di split ("/ n")?
jle


Penso che sarebbe meglio chiudere anche il file
Paweł Prażak

Risposte:


196
lines = open(filename).read().splitlines()

1
Questa risposta fa quello che stavo cercando, sono sicuro che avrò bisogno di aggiungere un po 'di controllo degli errori e simili, ma per questa specifica esigenza, è fantastico. Grazie a tutti per aver fornito risposte!
solarce

Mi piace ma come si chiude il file se non si salva dall'handle del file? O si chiude automaticamente?
IJ Kennedy

6
Con CPython, il conteggio dei riferimenti per l'oggetto file andrà a zero una volta che non è più in uso e il file verrà chiuso automaticamente. Per implementazioni puramente GC come Jython e IronPython, il file potrebbe non essere chiuso fino a quando il GC non viene eseguito, quindi questa variazione concisa potrebbe non essere ottimale.
Curt Hagenlocher

2
Su Mac OS X 10.7.5 con 8 GB di RAM, posso leggere file fino a 2047 MB ​​(la mia definizione: 1 MB = 1024 x 1024 byte). 2048 MB genererà un'eccezione MemoryError.
Hai Vu

1
@WKPlus Domanda eccellente: la risposta è "dipende" stackoverflow.com/a/15099341/994153 (CPython lo chiuderà poiché il conteggio dei riferimenti scende a zero, ma altre implementazioni Python potrebbero non chiuderlo, quindi è meglio renderlo esplicito )
Colin D Bennett

23

Ecco un generatore che fa quello che hai richiesto. In questo caso, l'uso di rstrip è sufficiente e leggermente più veloce di strip.

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

Tuttavia, molto probabilmente vorrai usarlo per sbarazzarti anche degli spazi vuoti finali.

lines = (line.rstrip() for line in open(filename))

Non dovrebbe essere [] intorno alla RHS, non ()?
andrewb

8
@andrewb Using () fornisce un'espressione generatrice, che non usa tanta memoria quanto l'uso di [] (una lista di comprensione.)
Jonathan Hartley

9

Cosa ne pensate di questo approccio?

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

L'espressione del generatore evita di caricare l'intero file in memoria e withgarantisce la chiusura del file


Questa è essenzialmente la stessa della risposta di @ TimoLinna pubblicata anni prima ...
martineau

8
for line in file('/tmp/foo'):
    print line.strip('\n')

4

Usa semplicemente le espressioni del generatore:

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

Inoltre, voglio consigliarti di non leggere l'intero file in memoria: il loop sui generatori è molto più efficiente su grandi set di dati.


3

Io uso questo

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

Allora posso fare cose come questa.

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

Oppure, posso estendere la pulizia con funzioni extra, ad esempio, eliminare righe vuote o saltare righe di commento o altro.


2

Lo farei così:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l

Sebbene la risposta di Curt Hagenlocher sia tecnicamente migliore, questa risposta è un buon punto di partenza se è necessario aggiungere altre elaborazioni a ciascuna riga.
TomOnTime

Non sono sicuro se fosse destinato a filtrare le righe vuote, ma questo è più conciso di ... if l.strip() is not '', che è ciò di cui ho bisogno nel mio caso.
Zach Young
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.