Est-ce la façon la plus propre d'écrire une liste dans un fichier, puisque writelines()
n'insère pas de caractères de nouvelle ligne ?
file.writelines(["%s\n" % item for item in list])
Il semble qu'il y aurait un moyen standard...
Est-ce la façon la plus propre d'écrire une liste dans un fichier, puisque writelines()
n'insère pas de caractères de nouvelle ligne ?
file.writelines(["%s\n" % item for item in list])
Il semble qu'il y aurait un moyen standard...
Vous pouvez utiliser une boucle :
with open('your_file.txt', 'w') as f:
for item in my_list:
f.write("%s\n" % item)
En Python 2, vous pouvez également utiliser
with open('your_file.txt', 'w') as f:
for item in my_list:
print >> f, item
Si vous tenez à un seul appel de fonction, supprimez au moins les crochets. []
de façon à ce que les chaînes à imprimer soient fabriquées une par une (un genexp plutôt qu'un listcomp) -- il n'y a aucune raison d'occuper toute la mémoire nécessaire pour matérialiser la liste entière des chaînes.
Ce n'est pas très complexe, mais pourquoi ne pas utiliser pickle ou json pour ne pas avoir à se soucier de la sérialisation et de la désérialisation ?
Par exemple, parce que vous voulez un fichier texte de sortie qui peut être facilement lu, modifié, etc., avec un élément par ligne. Ce n'est pas un désir rare;-).
Qu'allez-vous faire avec le fichier ? Ce fichier existe-t-il pour les humains, ou pour d'autres programmes ayant des exigences claires en matière d'interopérabilité ?
Si vous essayez simplement de sérialiser une liste sur le disque pour une utilisation ultérieure par la même application python, vous devriez décapage la liste.
import pickle
with open('outfile', 'wb') as fp:
pickle.dump(itemlist, fp)
Pour le relire :
with open ('outfile', 'rb') as fp:
itemlist = pickle.load(fp)
+1 - le fichier de sortie est quelque chose comme : open( "save.p", "wb" )
infile est quelque chose comme : open( "save.p", "rb" )
Le problème est que la liste doit tenir dans la mémoire. Si ce n'est pas le cas, la stratégie ligne par ligne est en effet envisageable (ou alors une alternative comme dans stackoverflow.com/questions/7180212/ )
La manière la plus simple est :
with open("outfile", "w") as outfile:
outfile.write("\n".join(itemlist))
Vous pouvez vous assurer que tous les éléments de la liste d'éléments sont des chaînes de caractères en utilisant une expression de générateur :
with open("outfile", "w") as outfile:
outfile.write("\n".join(str(item) for item in itemlist))
Rappelez-vous que tous les itemlist
doit être en mémoire, donc, faites attention à la consommation de mémoire.
Bien sûr, la première question qui vient à l'esprit est de savoir si le PO a besoin ou non qu'il se termine par une nouvelle ligne et si la quantité d'espace a de l'importance. Vous savez ce qu'on dit des optimisations prématurées.
Un inconvénient : Cette méthode construit tout le contenu du fichier en mémoire avant de l'écrire, de sorte que l'utilisation maximale de la mémoire peut être élevée.
Encore une autre façon. Sérialisez en json en utilisant simplejson (inclus comme json dans python 2.6) :
>>> import simplejson
>>> f = open('output.txt', 'w')
>>> simplejson.dump([1,2,3,4], f)
>>> f.close()
Si vous examinez le fichier de sortie.txt :
[1, 2, 3, 4]
C'est utile parce que la syntaxe est pythonique, qu'elle est lisible par l'homme et qu'elle peut être lue par d'autres programmes dans d'autres langues.
J'ai pensé qu'il serait intéressant d'explorer les avantages de l'utilisation d'un genexp, alors voici mon point de vue.
L'exemple de la question utilise des crochets pour créer une liste temporaire, et est donc équivalent à :
file.writelines( list( "%s\n" % item for item in list ) )
Ce qui construit inutilement une liste temporaire de toutes les lignes qui seront écrites, ce qui peut consommer des quantités significatives de mémoire en fonction de la taille de votre liste et du caractère verbeux de la sortie de la commande str(item)
est.
Supprimez les crochets (ce qui équivaut à supprimer l'emballage). list()
ci-dessus) transmettra à la place un générateur à file.writelines()
:
file.writelines( "%s\n" % item for item in list )
Ce générateur créera une représentation terminée par une nouvelle ligne de votre message. item
à la demande (c'est-à-dire au fur et à mesure qu'ils sont écrits). Ceci est intéressant pour plusieurs raisons :
str(item)
est lent, il y a une progression visible dans le fichier au fur et à mesure que chaque élément est traité.Cela évite les problèmes de mémoire, tels que :
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
(J'ai déclenché cette erreur en limitant la mémoire virtuelle maximale de Python à ~100 Mo avec la commande ulimit -v 102400
).
Si l'on met de côté l'utilisation de la mémoire, cette méthode n'est pas vraiment plus rapide que l'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 sous Linux)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
43 votes
Notez bien que
writelines
n'ajoute pas de nouvelles lignes parce qu'il reflète le modèlereadlines
qui ne les supprime pas non plus.0 votes
C'est entre json et pickle. lisez tout à ce sujet - stackoverflow.com/questions/27745500/