Scrivere un elenco in un file con Python


676

È questo il modo più pulito per scrivere un elenco in un file, dal momento writelines()che non inserisce caratteri di nuova riga?

file.writelines(["%s\n" % item  for item in list])

Sembra che ci sarebbe un modo standard ...


37
nota che writelinesnon aggiunge nuove righe perché rispecchia readlines, il che non le rimuove.
SingleNegationElimination

Risposte:


915

Puoi usare un loop:

with open('your_file.txt', 'w') as f:
    for item in my_list:
        f.write("%s\n" % item)

In Python 2, puoi anche usare

with open('your_file.txt', 'w') as f:
    for item in my_list:
        print >> f, item

Se sei appassionato di una singola chiamata di funzione, almeno rimuovi le parentesi quadre [], in modo che le stringhe da stampare vengano create una alla volta (un genexp anziché un listcomp) - nessun motivo per occupare tutta la memoria richiesta per materializzare l'intero elenco di stringhe.


7
Questo non è terribilmente complesso, ma perché non usare semplicemente pickle o json in modo da non doversi preoccupare della serializzazione e della deserializzazione?
Jason Baker,

82
Ad esempio perché si desidera un file di testo di output che può essere facilmente letto, modificato, ecc., Con un elemento per riga. Difficilmente un desiderio raro ;-).
Alex Martelli,

1
Ho scoperto che il \ n nel primo era ridondante su Python 2.7 / Windows
Jorge Rodriguez,

11
Questo alla fine scriverà un carattere extra di nuova riga ... piuttosto che loop, potresti semplicemente scriverethefile.write('\n'.join(thelist))
Tgsmith61591

3
Vorrei aggiungere: "Stai attento con il tipo di dati dell'elenco". Stavo ottenendo dei risultati strani, forse questo può aiutare qualcuno:thefile.write(str(item) + "\n")
Iipr,

384

Che cosa hai intenzione di fare con il file? Questo file esiste per gli esseri umani o altri programmi con chiari requisiti di interoperabilità?

Se stai solo cercando di serializzare un elenco su disco per un uso successivo da parte della stessa app Python, dovresti cercare l'elenco.

import pickle

with open('outfile', 'wb') as fp:
    pickle.dump(itemlist, fp)

Per rileggerlo:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)

35
+1 - Perché reinventare la ruota quando Python ha la serializzazione integrata?
Jason Baker,

20
+1 - outfile è qualcosa di simile: open( "save.p", "wb" ) infile è qualcosa di simile:open( "save.p", "rb" )
xxjjnn

2
Il problema è che l'elenco deve adattarsi alla memoria. In caso contrario, riga per riga è davvero una possibile strategia (oppure andare con qualche alternativa come in stackoverflow.com/questions/7180212/… )
Filippo Mazza,

1
In Python 2 usa 'r' invece di 'rb' quando leggi il pickle se ottieni "ValueError:
insecure

1
@serafeim: no; il with:blocco chiuderà il file prima di continuare con l'istruzione successiva al di fuori del withblocco.
SingleNegationElimination

286

Il modo più semplice è:

with open("outfile", "w") as outfile:
    outfile.write("\n".join(itemlist))

È possibile assicurarsi che tutti gli elementi nell'elenco degli elementi siano stringhe utilizzando un'espressione del generatore:

with open("outfile", "w") as outfile:
    outfile.write("\n".join(str(item) for item in itemlist))

Ricorda che tutti gli itemlistelenchi devono essere in memoria, quindi fai attenzione al consumo di memoria.


23
No newline finale, utilizza 2x spazio rispetto al loop.
Dave,

7
Naturalmente la prima domanda che mi viene in mente è se l'OP ha bisogno o meno di finire in una nuova riga e se la quantità di spazio è importante o meno. Sai cosa dicono delle ottimizzazioni premature.
Jason Baker,

15
Un aspetto negativo: questo costruisce l'intero contenuto del file in memoria prima di scriverne uno qualsiasi, quindi il picco di utilizzo della memoria potrebbe essere elevato.
RobM,

4
Non riesco mai a farlo funzionare. Ottengo questo errore: "text = '\ n'.join (elenco nomi) +' \ n 'TypeError: elemento sequenza 0: stringa prevista, elenco trovato"
Dan

2
Devi assicurarti che tutti gli elementi nell '"elenco nomi" siano stringhe.
osantana,

94

Uso della sintassi di Python 3 e Python 2.6+ :

with open(filepath, 'w') as file_handler:
    for item in the_list:
        file_handler.write("{}\n".format(item))

Questo è indipendente dalla piattaforma. Termina anche la riga finale con un carattere di nuova riga, che è una best practice UNIX .

A partire da Python 3.6, "{}\n".format(item)può essere sostituito con un F-stringa: f"{item}\n".


non voglio aggiungere "\ n" per l'ultimo elemento, cosa fare? non voglio se condizione
pyd

4
@pyd Sostituisci il ciclo for confile_handler.write("\n".join(str(item) for item in the_list))
orluke il

88

Ancora un altro modo. Serializza su json usando simplejson (incluso come json in python 2.6):

>>> import simplejson
>>> f = open('output.txt', 'w')
>>> simplejson.dump([1,2,3,4], f)
>>> f.close()

Se si esamina output.txt:

[1, 2, 3, 4]

Ciò è utile perché la sintassi è pitonica, è leggibile dall'uomo e può essere letta da altri programmi in altre lingue.


39

Ho pensato che sarebbe interessante esplorare i vantaggi dell'utilizzo di un genexp, quindi ecco la mia opinione.

L'esempio nella domanda usa parentesi quadre per creare un elenco temporaneo, quindi equivale a:

file.writelines( list( "%s\n" % item for item in list ) )

Che costruisce inutilmente un elenco temporaneo di tutte le righe che verranno scritte, ciò può consumare quantità significative di memoria a seconda delle dimensioni dell'elenco e di quanto sia dettagliato l'output di str(item).

Rilasciare le parentesi quadre (equivalenti a rimuovere la list()chiamata di wrapping sopra) passerà invece un generatore temporaneo a file.writelines():

file.writelines( "%s\n" % item for item in list )

Questo generatore creerà una rappresentazione con terminazione di nuova riga dei tuoi itemoggetti su richiesta (cioè quando vengono scritti). Questo è carino per un paio di motivi:

  • I costi di memoria sono piccoli, anche per elenchi molto grandi
  • Se str(item)è lento ci sono progressi visibili nel file mentre ogni elemento viene elaborato

Questo evita problemi di memoria, come:

In [1]: import os

In [2]: f = file(os.devnull, "w")

In [3]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 385 ms per loop

In [4]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.

Traceback (most recent call last):
...
MemoryError

(Ho attivato questo errore limitando la memoria virtuale massima di Python a ~ 100 MB con ulimit -v 102400).

Mettendo da parte l'utilizzo della memoria, questo metodo non è in realtà più veloce dell'originale:

In [4]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 370 ms per loop

In [5]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
1 loops, best of 3: 360 ms per loop

(Python 2.6.2 su Linux)


20

Perché sono pigro ...

import json
a = [1,2,3]
with open('test.txt', 'w') as f:
    f.write(json.dumps(a))

#Now read the file back into a Python list object
with open('test.txt', 'r') as f:
    a = json.loads(f.read())

le liste json sono serializzabili?
kRazzy R,

1
Sì davvero, lo sono!
CommandoScorch,

1
import json; test_list = [1,2,3]; list_as_a_string = json.dumps (test_list); #list_as_a_string è ora la stringa '[1,2,3]'
CommandoScorch

Lo sto facendo with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); il problema è che il mio programma viene eseguito tre volte e i risultati di tre esecuzioni si stanno purificando. c'è un modo per aggiungere 1-2 righe vuote in modo che i risultati di ciascuna corsa siano riconoscibili?
kRazzy R,

1
Assolutamente! potresti invece fare json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch,

19

Serializza l'elenco in un file di testo con un valore separato da virgola

mylist = dir()
with open('filename.txt','w') as f:
    f.write( ','.join( mylist ) )

14

In generale

Ciò che segue è la sintassi per writelines () metodo

fileObject.writelines( sequence )

Esempio

#!/usr/bin/python

# Open a file
fo = open("foo.txt", "rw+")
seq = ["This is 6th line\n", "This is 7th line"]

# Write sequence of lines at the end of the file.
line = fo.writelines( seq )

# Close opend file
fo.close()

Riferimento

http://www.tutorialspoint.com/python/file_writelines.htm



8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")

7

Puoi anche usare la funzione di stampa se sei su python3 come segue.

f = open("myfile.txt","wb")
print(mylist, file=f)

non è solo mettere una riga in myfile.txt, qualcosa del tipo: ['a', 'b', 'c'] invece di scrivere ciascuna a, b, c su ogni riga.
Harry Duong,

3

Perché non ci provi

file.write(str(list))

2

Questa logica convertirà innanzitutto gli elementi nell'elenco string(str). A volte l'elenco contiene una tupla come

alist = [(i12,tiger), 
(113,lion)]

Questa logica scriverà per archiviare ogni tupla in una nuova riga. In seguito possiamo usare evaldurante il caricamento di ogni tupla durante la lettura del file:

outfile = open('outfile.txt', 'w') # open a file in write mode
for item in list_to_persistence:    # iterate over the list items
   outfile.write(str(item) + '\n') # write to the file
outfile.close()   # close the file 

1

Un altro modo di iterare e aggiungere newline:

for item in items:
    filewriter.write(f"{item}" + "\n")

1

In python> 3 puoi usare printe *per spacchettare argomenti:

with open("fout.txt", "w") as fout:
    print(*my_list, sep="\n", file=fout)

-2

Lascia che avg sia l'elenco, quindi:

In [29]: a = n.array((avg))
In [31]: a.tofile('avgpoints.dat',sep='\n',dtype = '%f')

È possibile utilizzare %eo in %sbase alle proprie esigenze.


-2

In Python3 puoi usare questo loop

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)

-4
poem = '''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f = open('poem.txt', 'w') # open for 'w'riting
f.write(poem) # write text to file
f.close() # close the file

Come funziona: Innanzitutto, apri un file utilizzando la funzione di apertura integrata e specificando il nome del file e la modalità in cui vogliamo aprire il file. La modalità può essere una modalità di lettura ('r'), una modalità di scrittura ('w') o una modalità di aggiunta ('a'). Possiamo anche specificare se stiamo leggendo, scrivendo o aggiungendo in modalità testo ('t') o binaria ('b'). In realtà ci sono molte altre modalità disponibili e aiuto (aperto) ti darà maggiori dettagli su di esse. Per impostazione predefinita, open () considera il file come file 't'ext e lo apre in modalità' r'ead. Nel nostro esempio, apriamo prima il file in modalità di scrittura del testo e utilizziamo il metodo write dell'oggetto file per scrivere sul file, quindi chiudiamo il file.

L'esempio sopra è tratto dal libro "A Byte of Python" di Swaroop C H. swaroopch.com


5
Questo scrive una stringa in un file, non in un elenco (di stringhe) come chiede l'OP
gwideman
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.