Então, eu estou aprendendo Python. Estou passando pelas lições e tive um problema em que tive que condensar muitos target.write()
em um único write()
, enquanto tinha uma "\n"
variável de entrada entre cada usuário (o objeto de write()
).
Eu vim com:
nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)
Se eu tentar fazer:
textdoc.write(lines)
Eu recebo um erro. Mas se eu digitar:
textdoc.write(line1 + "\n" + line2 + ....)
Então funciona bem. Por que não consigo usar uma string para uma nova linha, write()
mas posso usá-la writelines()
?
Python 2.7 Quando pesquisei no google a maioria dos recursos que encontrei, estava na minha cabeça, ainda sou um leigo.
python
string
file-io
python-2.x
AbeLinkon
fonte
fonte
lines
não é uma string no seu exemplo. É uma tupla composta por seis cordas.Respostas:
writelines
espera um iterável de stringswrite
espera uma única sequência.line1 + "\n" + line2
mescla essas strings em uma única string antes de passá-las parawrite
.Observe que, se você tiver muitas linhas, poderá usar
"\n".join(list_of_lines)
.fonte
writelines
espera um iterável. Você pode usar uma lista, uma tupla ou um gerador.write
vez dewritelines
se tiver muitas linhas? Writelines pode ter um desempenho melhor, pois não precisa criar uma sequência concatenada temporária, apenas repetindo as linhas.Por que não consigo usar uma string para uma nova linha em write (), mas posso usá-la em writelines ()?
A idéia é a seguinte: se você deseja escrever uma única string, pode fazê-lo
write()
. Se você tiver uma sequência de strings, poderá escrever todas elas usandowritelines()
.write(arg)
espera uma string como argumento e a grava no arquivo Se você fornecer uma lista de strings, isso gerará uma exceção (a propósito, mostre erros para nós!).writelines(arg)
espera um argumento iterável como (um objeto iterável pode ser uma tupla, uma lista, uma string ou um iterador no sentido mais geral). Espera-se que cada item contido no iterador seja uma sequência. Uma tupla de strings é o que você forneceu, para que as coisas funcionassem.A natureza das strings não importa para as duas funções, ou seja, elas apenas gravam no arquivo o que você fornecer. A parte interessante é que
writelines()
não adiciona caracteres de nova linha por conta própria, portanto o nome do método pode ser bastante confuso. Na verdade, ele se comporta como um método imaginário chamadowrite_all_of_these_strings(sequence)
.A seguir, é uma maneira idiomática no Python para escrever uma lista de strings em um arquivo, mantendo cada string em sua própria linha:
Isso cuida do fechamento do arquivo para você. A construção
'\n'.join(lines)
concatena (conecta) as seqüências de caracteres na listalines
e usa o caractere '\ n' como cola. É mais eficiente do que usar o+
operador.Começando na mesma
lines
sequência, terminando com a mesma saída, mas usandowritelines()
:Isso faz uso de uma expressão de gerador e cria dinamicamente seqüências terminadas em nova linha.
writelines()
itera sobre essa sequência de strings e grava todos os itens.Edit: Outro ponto que você deve estar ciente de:
write()
ereadlines()
existia antes dewritelines()
ser introduzido.writelines()
foi introduzido mais tarde como uma contrapartida dereadlines()
, para que se pudesse escrever facilmente o conteúdo do arquivo que acabou de ser lido através dereadlines()
:Realmente, essa é a principal razão pela qual
writelines
esse nome é confuso. Além disso, hoje, realmente não queremos mais usar esse método.readlines()
lê o arquivo inteiro na memória da sua máquina antes dewritelines()
começar a gravar os dados. Primeiro de tudo, isso pode perder tempo. Por que não começar a escrever partes dos dados enquanto lê outras partes? Mas, o mais importante, essa abordagem pode consumir muita memória. Em um cenário extremo, onde o arquivo de entrada é maior que a memória da sua máquina, essa abordagem nem funciona. A solução para esse problema é usar apenas iteradores. Um exemplo de trabalho:Isso lê o arquivo de entrada linha por linha. Assim que uma linha é lida, essa linha é gravada no arquivo de saída. Esquematicamente falado, sempre há apenas uma única linha na memória (em comparação com todo o conteúdo do arquivo na memória, no caso da abordagem de linhas de leitura / linhas de escrita).
fonte
write()
ewritelines()
são basicamente equivalentes e seu uso também é uma questão de gosto pessoal. No entanto, é importante observar que, para uma lista extremamente longa de strings (chamadalines
), é menos eficiente escrever dof.write('\n'.join(lines))
quefor l in line: f.write('%s\n' % l)
. No primeiro caso, uma sequência inteiramente nova e muito longa é criada na memória antes de gravá-la. No segundo caso, os dados são escritos por partes.outf.writelines(inf.readlines())
mas simoutf.writelines(inf)
. A função que não queremos mais usarreadlines()
não éwritelines()
.writelines()
, sua semântica é, como explicado, menos que o ideal. É por isso que nunca o usei. E eu nunca senti falta disso.se você quiser salvar e carregar uma lista, tente Pickle
Economia de picles:
e carregamento:
fonte
Na verdade, acho que o problema é que suas "linhas" variáveis são ruins. Você definiu linhas como uma tupla, mas acredito que write () requer uma string. Tudo o que você precisa alterar são suas vírgulas em vantagens (+).
Deveria trabalhar.
fonte
Exercício 16 do livro de Zed Shaw? Você pode usar caracteres de escape da seguinte maneira:
fonte
" \n ".join((line1, line2, line3))
.