Alors j'apprends Python. Je suis en train de parcourir les leçons et j'ai rencontré un problème où j'ai dû en condenser un grand nombre target.write()
en un seul write()
, tout en ayant une "\n"
variable d'entrée entre chaque utilisateur (l'objet de write()
).
Je suis venu avec:
nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)
Si j'essaye de faire:
textdoc.write(lines)
J'obtiens une erreur. Mais si je tape:
textdoc.write(line1 + "\n" + line2 + ....)
Ensuite, cela fonctionne très bien. Pourquoi suis-je incapable d'utiliser une chaîne pour une nouvelle ligne dans write()
mais je peux l'utiliser dans writelines()
?
Python 2.7 Quand j'ai cherché sur Google, la plupart des ressources que j'ai trouvées étaient bien au-dessus de ma tête, je suis toujours un profane.
python
string
file-io
python-2.x
AbeLinkon
la source
la source
lines
n'est pas une chaîne dans votre exemple. C'est un tuple composé de six chaînes.Réponses:
writelines
attend un itérable de chaîneswrite
attend une seule chaîne.line1 + "\n" + line2
fusionne ces chaînes en une seule chaîne avant de la transmettrewrite
.Notez que si vous avez plusieurs lignes, vous pouvez utiliser
"\n".join(list_of_lines)
.la source
writelines
attend un itérable. Vous pouvez utiliser une liste, un tuple ou un générateur.write
au lieu dewritelines
si vous avez plusieurs lignes? Les écritures pourraient être plus performantes car il n'est pas nécessaire de créer une chaîne concaténée temporaire, juste une itération sur les lignes.Pourquoi suis-je incapable d'utiliser une chaîne pour une nouvelle ligne dans write () mais je peux l'utiliser dans writelines ()?
L'idée est la suivante: si vous voulez écrire une seule chaîne, vous pouvez le faire avec
write()
. Si vous avez une séquence de chaînes, vous pouvez toutes les écrire en utilisantwritelines()
.write(arg)
attend une chaîne comme argument et l'écrit dans le fichier. Si vous fournissez une liste de chaînes, cela lèvera une exception (au fait, montrez-nous les erreurs!).writelines(arg)
attend un itérable comme argument (un objet itérable peut être un tuple, une liste, une chaîne ou un itérateur au sens le plus général). Chaque élément contenu dans l'itérateur doit être une chaîne. Un tuple de chaînes est ce que vous avez fourni, donc les choses ont fonctionné.La nature de la ou des chaînes n'a pas d'importance pour les deux fonctions, c'est-à-dire qu'elles écrivent simplement dans le fichier tout ce que vous leur fournissez. La partie intéressante est qu'elle
writelines()
n'ajoute pas de caractères de nouvelle ligne en soi, de sorte que le nom de la méthode peut en fait être assez déroutant. Il se comporte en fait comme une méthode imaginaire appeléewrite_all_of_these_strings(sequence)
.Ce qui suit est une manière idiomatique en Python d'écrire une liste de chaînes dans un fichier tout en gardant chaque chaîne dans sa propre ligne:
Cela prend soin de fermer le fichier pour vous. La construction
'\n'.join(lines)
concatène (connecte) les chaînes de la listelines
et utilise le caractère '\ n' comme colle. C'est plus efficace que d'utiliser l'+
opérateur.À partir de la même
lines
séquence, se terminant avec la même sortie, mais en utilisantwritelines()
:Cela utilise une expression de générateur et crée dynamiquement des chaînes terminées par une nouvelle ligne.
writelines()
itère sur cette séquence de chaînes et écrit chaque élément.Edit: Un autre point dont vous devez être conscient:
write()
etreadlines()
existait avant awritelines()
été introduit.writelines()
a été introduit plus tard en tant que contrepartie dereadlines()
, afin que l'on puisse facilement écrire le contenu du fichier qui vient d'être lu viareadlines()
:Vraiment, c'est la principale raison pour laquelle
writelines
a un nom si déroutant. Aussi, aujourd'hui, nous ne voulons plus vraiment utiliser cette méthode.readlines()
lit le fichier entier dans la mémoire de votre machine avant dewritelines()
commencer à écrire les données. Tout d'abord, cela peut perdre du temps. Pourquoi ne pas commencer à écrire des parties de données tout en lisant d'autres parties? Mais, plus important encore, cette approche peut être très gourmande en mémoire. Dans un scénario extrême, où le fichier d'entrée est plus volumineux que la mémoire de votre machine, cette approche ne fonctionnera même pas. La solution à ce problème consiste à n'utiliser que des itérateurs. Un exemple de travail:Cela lit le fichier d'entrée ligne par ligne. Dès qu'une ligne est lue, cette ligne est écrite dans le fichier de sortie. En termes schématiques, il n'y a toujours qu'une seule ligne en mémoire (par rapport au contenu entier du fichier étant en mémoire dans le cas de l'approche readlines / writelines).
la source
write()
etwritelines()
sont fondamentalement équivalents et leur utilisation est également une question de goût personnel. Cependant, il est important de noter que pour une liste extrêmement longue de chaînes (appeléeslines
), il est moins efficace d'écriref.write('\n'.join(lines))
quefor l in line: f.write('%s\n' % l)
. Dans le premier cas, une chaîne entièrement nouvelle et très longue est créée en mémoire avant de l'écrire. Dans le second cas, les données sont écrites par morceaux.outf.writelines(inf.readlines())
mais plutôtoutf.writelines(inf)
. La fonction que nous ne voulons plus utiliserreadlines()
ne l' est pluswritelines()
.writelines()
, sa sémantique est, comme expliqué, loin d'être idéale. C'est pourquoi je ne l'ai jamais utilisé. Et je ne l'ai jamais manqué.si vous voulez juste enregistrer et charger une liste, essayez Pickle
Économie de cornichon:
et chargement:
la source
En fait, je pense que le problème est que vos "lignes" variables sont mauvaises. Vous avez défini les lignes comme un tuple, mais je pense que write () nécessite une chaîne. Tout ce que vous avez à changer, ce sont vos virgules en plus (+).
devrait marcher.
la source
Exercice 16 du livre de Zed Shaw? Vous pouvez utiliser les caractères d'échappement comme suit:
la source
" \n ".join((line1, line2, line3))
.