Escrevendo uma lista em um arquivo com Python

672

É a maneira mais limpa de escrever uma lista em um arquivo, pois writelines()não insere caracteres de nova linha?

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

Parece que haveria uma maneira padrão ...

Josh Arenberg
fonte
37
observe que writelinesnão adiciona novas linhas porque reflete readlines, o que também não as remove.
SingleNegationElimination

Respostas:

908

Você pode usar um loop:

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

No Python 2, você também pode usar

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

Se você estiver interessado em uma única chamada de função, remova os colchetes, pelo menos [], para que as seqüências a serem impressas sejam feitas uma de cada vez (um genexp em vez de um listcomp) - não há razão para ocupar toda a memória necessária para materializar toda a lista de strings.

Alex Martelli
fonte
7
Isso não é muito complexo, mas por que não usar pickle ou json para que você não precise se preocupar com a serialização e desserialização?
213 Jason Baker
82
Por exemplo, porque você deseja um arquivo de texto de saída que possa ser facilmente lido, editado etc. com um item por linha. Dificilmente um desejo raro ;-).
Alex Martelli
1
Eu achei que o \ n na primeira era redundante em Python 2.7 / Windows
Jorge Rodriguez
11
Isto irá escrever um caractere de nova linha extra no final ... em vez de loop, você poderia apenas escreverthefile.write('\n'.join(thelist))
Tgsmith61591
3
Eu acrescentaria: "Cuidado com o tipo de dados da lista". Eu estava obtendo resultados estranhos, talvez isso possa ajudar alguém:thefile.write(str(item) + "\n")
iipr 11/11/17
383

O que você vai fazer com o arquivo? Esse arquivo existe para humanos ou outros programas com requisitos claros de interoperabilidade?

Se você está apenas tentando serializar uma lista em disco para uso posterior pelo mesmo aplicativo python, você deve selecionar a lista.

import pickle

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

Para ler de volta:

with open ('outfile', 'rb') as fp:
    itemlist = pickle.load(fp)
SingleNegationElimination
fonte
35
+1 - Por que reinventar a roda quando o Python possui serialização integrada?
213 Jason Baker
20
+1 - outfile é algo como: open( "save.p", "wb" ) infile é algo como:open( "save.p", "rb" )
xxjjnn
2
O problema é que a lista deve caber na memória. Se este não for o caso, linha por linha é de fato uma possível estratégia (ou então ir com alguma alternativa como em stackoverflow.com/questions/7180212/... )
Filippo Mazza
1
No Python 2, use 'r' em vez de 'rb' ao ler o pickle se você receber "ValueError: pickle de string inseguro"
queise
1
@serafeim: não; o with:bloco fechará o arquivo antes de continuar para a próxima instrução fora do withbloco.
SingleNegationElimination
285

A maneira mais simples é:

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

Você pode garantir que todos os itens da lista de itens sejam cadeias usando uma expressão geradora:

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

Lembre-se de que toda a itemlistlista precisa estar na memória; portanto, tome cuidado com o consumo de memória.

osantana
fonte
23
Sem nova linha à direita, usa espaço 2x em comparação ao loop.
22409 Dave
7
É claro que a primeira pergunta que vem à mente é se o OP precisa ou não terminar em uma nova linha e se a quantidade de espaço importa ou não. Você sabe o que eles dizem sobre otimizações prematuras.
213 Jason Baker
15
Uma desvantagem: Isso constrói todo o conteúdo do arquivo na memória antes de gravá-los, para que o uso máximo da memória possa ser alto.
RobM
4
Eu nunca consigo fazer isso funcionar. Eu recebo este erro: "text = '\ n'.join (lista de nomes) +' \ n 'TypeError: item de sequência 0: sequência esperada, lista encontrada"
Dan
2
Você deve garantir que todos os elementos na 'lista de nomes' sejam cadeias.
Osantana 10/08
94

Usando a sintaxe Python 3 e Python 2.6 ou superior :

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

Isso é independente de plataforma. Ele também finaliza a linha final com um caractere de nova linha, que é uma prática recomendada do UNIX .

Começando com Python 3.6, "{}\n".format(item)pode ser substituído por um f-string: f"{item}\n".

orluke
fonte
não quero adicionar "\ n" para o último item, o que fazer? Não queira se a condição
PYD
4
@pyd Substitua o loop for porfile_handler.write("\n".join(str(item) for item in the_list))
orluke
88

Mais uma maneira. Serialize para json usando simplejson (incluído como json no python 2.6):

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

Se você examinar o output.txt:

[1, 2, 3, 4]

Isso é útil porque a sintaxe é pitônica, é legível por humanos e pode ser lida por outros programas em outros idiomas.

Jason Baker
fonte
39

Eu pensei que seria interessante explorar os benefícios de usar um genexp, então aqui está minha opinião.

O exemplo na pergunta usa colchetes para criar uma lista temporária e, portanto, é equivalente a:

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

Que desnecessariamente constrói uma lista temporária de todas as linhas que serão gravadas, isso pode consumir quantidades significativas de memória, dependendo do tamanho da sua lista e quão detalhada é a saída str(item).

Solte os colchetes (equivalente a remover a list()chamada de empacotamento acima) e, em vez disso, passará um gerador temporário para file.writelines():

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

Este gerador criará uma representação terminada em nova linha de seus itemobjetos sob demanda (ou seja, conforme eles são gravados). Isso é bom por alguns motivos:

  • As despesas gerais de memória são pequenas, mesmo para listas muito grandes
  • Se str(item)for lento, há progresso visível no arquivo à medida que cada item é processado

Isso evita problemas de memória, 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

(Acionei esse erro limitando a memória virtual máxima do Python a ~ 100 MB ulimit -v 102400).

Colocando o uso da memória de lado, esse método não é mais rápido que o 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 no Linux)

RobM
fonte
20

Porque eu sou preguiçoso ....

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())
CommandoScorch
fonte
as listas json são serializáveis?
precisa saber é o seguinte
1
Sim, de fato, eles são!
CommandoScorch
1
importação json; lista_teste = [1,2,3]; list_as_a_string = json.dumps (lista de teste); #list_as_a_string agora é a string '[1,2,3]'
CommandoScorch
Eu estou fazendo isso with open ('Sp1.txt', 'a') as outfile: json.dump (sp1_segments, outfile) logger.info ("Saved sp_1 segments"); O problema é que meu programa é executado três vezes e os resultados de três execuções estão sendo misturados. existe alguma maneira de adicionar 1-2 linhas vazias para que os resultados de cada execução sejam discerníveis?
precisa saber é o seguinte
1
Absolutamente! você poderia fazer json.dump(sp1_segments + "\n\n", outfile)?
CommandoScorch
19

Serializar lista em arquivo de texto com valor separado por vírgula

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

Em geral

A seguir está a sintaxe do método writelines ()

fileObject.writelines( sequence )

Exemplo

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

Referência

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

Marvin W
fonte
13
file.write('\n'.join(list))
mtasic85
fonte
1
Deve-se notar que isso exigirá que o arquivo seja aberto como texto para ser verdadeiramente neutro em plataforma.
214 Jason Baker
2
Como você obtém a filevariável?
Jonathan Morales Vélez
8
with open ("test.txt","w")as fp:
   for line in list12:
       fp.write(line+"\n")
Shankar
fonte
7

Você também pode usar a função de impressão se estiver no python3 da seguinte maneira.

f = open("myfile.txt","wb")
print(mylist, file=f)
Nandita Damaraju
fonte
não é só colocar uma linha em myfile.txt, algo como: ['a', 'b', 'c'] em vez de escrever cada a, b, c em cada linha.
Harry Duong
3

Por que você não tenta

file.write(str(list))
Prumo
fonte
2

Essa lógica primeiro converterá os itens da lista em string(str). Às vezes, a lista contém uma tupla como

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

Essa lógica gravará para arquivar cada tupla em uma nova linha. Posteriormente, podemos usar o evalcarregamento de cada tupla ao ler o arquivo:

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
fonte
1

Outra maneira de iterar e adicionar nova linha:

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

Em python> 3 você pode usar printe *para descompactar argumentos:

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

No Python3, você pode usar esse loop

with open('your_file.txt', 'w') as f:
    for item in list:
        f.print("", item)
Nikhil B
fonte
-3

Seja avg a lista, então:

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

Você pode usar %eou %sdependendo de sua exigência.

Belthazar
fonte
-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

Como funciona: Primeiro, abra um arquivo usando a função aberta integrada e especificando o nome do arquivo e o modo em que queremos abrir o arquivo. O modo pode ser um modo de leitura ('r'), modo de gravação ('w') ou modo de adição ('a'). Também podemos especificar se estamos lendo, escrevendo ou acrescentando no modo de texto ('t') ou no modo binário ('b'). Na verdade, existem muitos outros modos disponíveis e a ajuda (aberta) fornecerá mais detalhes sobre eles. Por padrão, open () considera o arquivo como um arquivo 't'ext e o abre no modo' r'ead. Em nosso exemplo, primeiro abrimos o arquivo no modo de gravação de texto e usamos o método write do objeto de arquivo para gravar no arquivo e depois fechamos o arquivo.

O exemplo acima é do livro "A Byte of Python" de Swaroop C H. swaroopch.com

vayah
fonte
5
Este escreve uma string para um arquivo, e não uma lista (de cordas) como o OP pede
gwideman