Escribir una lista en un archivo con Python

676

¿Es esta la forma más limpia de escribir una lista en un archivo, ya writelines()que no inserta caracteres de nueva línea?

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

Parece que habría una forma estándar ...

Josh Arenberg
fuente
37
tenga en cuenta que writelinesno agrega nuevas líneas porque refleja readlines, lo que tampoco las elimina.
SingleNegationElimination

Respuestas:

915

Puedes usar un bucle:

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

En Python 2, también puedes usar

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

Si está interesado en una sola llamada de función, al menos elimine los corchetes [], de modo que las cadenas que se imprimirán se hagan una a la vez (un genexp en lugar de un listcomp), no hay razón para ocupar toda la memoria requerida para materializar toda la lista de cadenas.

Alex Martelli
fuente
77
Esto no es terriblemente complejo, pero ¿por qué no solo usar pickle o json para que no tenga que preocuparse por la serialización y la deserialización?
Jason Baker
82
Por ejemplo, porque desea un archivo de texto de salida que se pueda leer, editar, etc., fácilmente, con un elemento por línea. Apenas un deseo raro ;-).
Alex Martelli
1
Descubrí que el \ n en el primero era redundante en Python 2.7 / Windows
Jorge Rodriguez
11
Esto escribirá un carácter de nueva línea adicional al final ... en lugar de bucle, podría simplemente escribirthefile.write('\n'.join(thelist))
Tgsmith61591
3
Yo agregaría: "Tenga cuidado con el tipo de datos de la lista". Estaba obteniendo algunos resultados extraños, tal vez esto pueda ayudar a alguien:thefile.write(str(item) + "\n")
iipr
384

¿Qué vas a hacer con el archivo? ¿Existe este archivo para humanos u otros programas con requisitos claros de interoperabilidad?

Si solo está tratando de serializar una lista en el disco para su uso posterior por la misma aplicación de Python, debería seleccionar la lista.

import pickle

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

Para leerlo de nuevo:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)
SingleNegationElimination
fuente
35
+1 - ¿Por qué reinventar la rueda cuando Python tiene incorporada la serialización?
Jason Baker
20
+1 - outfile es algo como: open( "save.p", "wb" ) infile es algo como:open( "save.p", "rb" )
xxjjnn
2
El problema es que la lista debe caber en la memoria. Si este no es el caso, línea por línea es, de hecho, una estrategia posible (o de lo contrario ir con alguna alternativa como en stackoverflow.com/questions/7180212/… )
Filippo Mazza
1
En Python 2 use 'r' en lugar de 'rb' al leer el pickle si obtiene el "ValueError: inseguro string pickle"
consulta el
1
@serafeim: no; el with:bloque cerrará el archivo antes de continuar con la siguiente declaración fuera del withbloque.
SingleNegationElimination
286

La forma más simple es:

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

Puede asegurarse de que todos los elementos de la lista de elementos sean cadenas utilizando una expresión generadora:

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

Recuerde que todas las itemlistlistas deben estar en la memoria, por lo tanto, tenga cuidado con el consumo de memoria.

osantana
fuente
23
Sin nueva línea final, utiliza 2 veces el espacio en comparación con el bucle.
Dave
77
Por supuesto, la primera pregunta que me viene a la mente es si el OP necesita o no terminar en una nueva línea y si la cantidad de espacio es importante o no. Ya sabes lo que dicen sobre optimizaciones prematuras.
Jason Baker
15
Una desventaja: construye todo el contenido del archivo en la memoria antes de escribir cualquiera de ellos, por lo que el uso máximo de memoria puede ser alto.
RobM
44
Nunca puedo hacer que esto funcione. Recibo este error: "text = '\ n'.join (namelist) +' \ n 'TypeError: elemento de secuencia 0: cadena esperada, lista encontrada"
Dan
2
Debe asegurarse de que todos los elementos en 'namelist' sean cadenas.
osantana
94

Usando Python 3 y Python 2.6+ sintaxis:

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

Esto es independiente de la plataforma. También termina la línea final con un carácter de nueva línea, que es una práctica recomendada para UNIX .

A partir de Python 3.6, "{}\n".format(item)se puede sustituir por un F-secuencia f"{item}\n".

orluke
fuente
no quiero agregar "\ n" para el último elemento, ¿qué hacer? no quiero si condición
pyd
44
@pyd Reemplace el bucle for confile_handler.write("\n".join(str(item) for item in the_list))
orluke
88

Otra forma más. Serialice a json usando simplejson (incluido como json en python 2.6):

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

Si examina output.txt:

[1, 2, 3, 4]

Esto es útil porque la sintaxis es pitónica, es legible por humanos y otros programas la pueden leer en otros idiomas.

Jason Baker
fuente
39

Pensé que sería interesante explorar los beneficios de usar un genexp, así que aquí está mi opinión.

El ejemplo en la pregunta usa corchetes para crear una lista temporal, y es equivalente a:

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

Lo cual construye innecesariamente una lista temporal de todas las líneas que se escribirán, esto puede consumir cantidades significativas de memoria dependiendo del tamaño de su lista y de cuán detallada es la salida de str(item).

Eliminar los corchetes (equivalente a eliminar la list()llamada de ajuste anterior) en su lugar pasará un generador temporal a file.writelines():

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

Este generador creará una representación terminada en línea de sus itemobjetos a pedido (es decir, a medida que se escriben). Esto es bueno por un par de razones:

  • Los gastos generales de memoria son pequeños, incluso para listas muy grandes
  • Si str(item)es lento, hay un progreso visible en el archivo a medida que se procesa cada elemento

Esto evita problemas de memoria, como:

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

(Activé este error al limitar la memoria virtual máxima de Python a ~ 100 MB con ulimit -v 102400).

Poniendo el uso de la memoria a un lado, este método en realidad no es más rápido que el original:

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 en Linux)

RobM
fuente
20

Porque soy vago ...

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())
ComandoScorch
fuente
¿son listas json serializables?
kRazzy R
1
Sí, de hecho, lo son!
CommandoScorch
1
importar json; lista_test = [1,2,3]; list_as_a_string = json.dumps (test_list); #list_as_a_string ahora es la cadena '[1,2,3]'
CommandoScorch
Estoy haciendo esto with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); El problema es que mi programa se ejecuta tres veces y los resultados de tres ejecuciones se están mezclando. ¿Hay alguna manera de agregar 1-2 líneas vacías para que los resultados de cada ejecución sean discernibles?
kRazzy R
1
¡Absolutamente! ¿podrías hacer en su lugar json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch
19

Serialice la lista en un archivo de texto con un valor separado por comas

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

En general

La siguiente es la sintaxis para el método writelines ()

fileObject.writelines( sequence )

Ejemplo

#!/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()

Referencia

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

Marvin W
fuente
13
file.write('\n'.join(list))
mtasic85
fuente
1
Se debe tener en cuenta que esto requerirá que el archivo se abra como texto para ser verdaderamente neutral en la plataforma.
Jason Baker
2
¿Cómo se obtiene la filevariable?
Jonathan Morales Vélez
8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")
shankar
fuente
7

También puede usar la función de impresión si está en python3 de la siguiente manera.

f = open("myfile.txt","wb")
print(mylist, file=f)
Nandita Damaraju
fuente
no es solo poner una línea en myfile.txt, algo así como: ['a', 'b', 'c'] en lugar de escribir cada a, b, c en cada línea.
Harry Duong
3

¿Por qué no lo intentas?

file.write(str(list))
Beto
fuente
2

Esta lógica primero convertirá los elementos de la lista a string(str). A veces la lista contiene una tupla como

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

Esta lógica escribirá para archivar cada tupla en una nueva línea. Luego podemos usar evalmientras cargamos cada tupla al leer el archivo:

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 
Tahir Ahmad
fuente
1

Otra forma de iterar y agregar nueva línea:

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

En python> 3 puede usar printy *para desempaquetar argumentos:

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

Deje que avg sea la lista, luego:

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

Puede usar %eo %ssegún su requerimiento.

belthazar
fuente
-2

En Python3 puedes usar este bucle

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)
Nikhil B
fuente
-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

Cómo funciona: Primero, abra un archivo utilizando la función de apertura incorporada y especificando el nombre del archivo y el modo en el que queremos abrir el archivo. El modo puede ser un modo de lectura ('r'), un modo de escritura ('w') o un modo de adición ('a'). También podemos especificar si estamos leyendo, escribiendo o agregando en modo de texto ('t') o en modo binario ('b'). En realidad, hay muchos más modos disponibles y la ayuda (abierta) le dará más detalles sobre ellos. Por defecto, open () considera que el archivo es un 't'extfiche y lo abre en modo' r'ead. En nuestro ejemplo, primero abrimos el archivo en modo de escritura de texto y usamos el método de escritura del objeto de archivo para escribir en el archivo y luego cerramos finalmente el archivo.

El ejemplo anterior es del libro "A Byte of Python" de Swaroop C H. swaroopch.com

vayah
fuente
55
Esto escribe una cadena en un archivo, no una lista (de cadenas) como el PO pide
gwideman