HOWTO · Python
Come leggere un file riga per riga ad una lista in Python
Questo tutorial introduce come leggere un file riga per riga in una lista in Python
In questa pagina
Per trasformare un file di testo in una lista, scegli un metodo in base alla necessità di conservare i terminatori di riga e alla quantità di dati che può stare in memoria. Apri i file di testo specificando la codifica, così Python decodifica i byte in modo coerente. Gli esempi seguenti creano autonomamente un file di piccole dimensioni, quindi puoi adattarli senza dipendere da un percorso specifico.
Usare readlines() per creare una lista di righe
Il metodo readlines() legge il resto del flusso e restituisce una lista con una stringa per ogni riga. In modalità testo, i caratteri di fine riga normalmente restano nelle stringhe. La gestione predefinita delle nuove righe universali di Python converte i terminatori comuni in ingresso in \n; l’ultima riga, se non ha un terminatore, rimane senza. La lista contiene quindi il testo e i terminatori di riga presenti.
Esegui questo esempio autonomo per creare una lista mantenendo i caratteri di nuova riga restituiti da readlines():
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("Line One: 1\nLine Two: 2\nLine Three: 3\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = file.readlines()
print(lines)
Se vuoi il testo senza il carattere di avanzamento riga, applica rstrip("\n") a ogni stringa. In questo modo rimuovi i caratteri di avanzamento riga finali, conservando spazi e tabulazioni che potrebbero far parte del contenuto. Evita di rimuovere tutti gli spazi bianchi, a meno che ciò non rientri nelle regole di pulizia dei tuoi dati.
Iterare sul file per evitare di caricare tutte le righe in una volta
È possibile iterare direttamente su un oggetto file di testo. La lettura avviene una riga alla volta, evitando di creare prima la lista aggiuntiva di tutte le righe che restituisce readlines(). Se però aggiungi ogni riga a una lista di risultati, la lista finale continua a contenere tutto il testo del file e richiede memoria proporzionale alla sua dimensione.
L’esempio seguente crea la lista richiesta rimuovendo da ogni riga solo il suffisso di avanzamento riga:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("Line One: 1\nLine Two: 2\nLine Three: 3\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = [line.rstrip("\n") for line in file]
print(lines)
Se il file è troppo grande per conservarlo in una lista, elabora ogni riga all’interno del blocco with senza aggiungerla a una lista. Per esempio, puoi verificare una condizione, aggiornare un conteggio progressivo oppure scrivere i dati trasformati in un altro file. In questo modo elabori il flusso senza mantenere in memoria tutte le righe di input, anche se le altre strutture dati usate dall’operazione continuano a occupare memoria.
Usare read().splitlines() quando l’intero file può stare in memoria
Chiamare read() senza specificare una dimensione legge dalla posizione corrente fino alla fine del file (EOF) e restituisce un’unica stringa. Chiamare splitlines() su quella stringa crea una lista delle sue righe. Per impostazione predefinita, splitlines() rimuove i terminatori di riga; passa keepends=True per conservarli. Poiché la stringa completa esiste prima della creazione della lista, questo approccio può mantenere temporaneamente in memoria sia il testo del file sia la lista delle sue parti.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("Line One: 1\nLine Two: 2\nLine Three: 3\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines_without_endings = file.read().splitlines()
with path.open("r", encoding="utf-8") as file:
lines_with_endings = file.read().splitlines(keepends=True)
print(lines_without_endings)
print(lines_with_endings)
Scegliere il metodo in base alla memoria e ai terminatori di riga
Usa readlines() se vuoi una lista e ti è utile conservare i terminatori di riga. Itera sul file se vuoi elaborare i dati progressivamente oppure se ti serve una lista ma vuoi evitare una lista intermedia aggiuntiva. Scegli read().splitlines() quando l’intero file può stare comodamente in memoria e preferisci un modo conciso per ottenere stringhe senza terminatori di riga; imposta keepends=True se vuoi conservarli.
Nessun metodo rende gratuita la memorizzazione di una lista completa: sia le stringhe sia la struttura della lista occupano memoria. Se il file è così grande che creare la lista richiesta rischia di causare MemoryError, modifica l’operazione in modo da elaborare ogni riga man mano che arriva, senza accumularle tutte. Questi metodi hanno comportamenti diversi per memoria e terminatori di riga: scegli quello che corrisponde al risultato richiesto, senza presumere che uno sia sempre più veloce degli altri.