Créer un fichier .csv avec les valeurs d'une liste Python

182

J'essaye de créer un fichier .csv avec les valeurs d'une liste Python. Lorsque j'imprime les valeurs dans la liste, elles sont toutes unicode (?), C'est-à-dire qu'elles ressemblent à ceci

[u'value 1', u'value 2', ...]

Si je parcours les valeurs de la liste, c'est-à-dire for v in mylist: print v qu'elles semblent être du texte brut.

Et je peux mettre un ,entre chacun avecprint ','.join(mylist)

Et je peux sortir dans un fichier, c'est à dire

myfile = open(...)
print >>myfile, ','.join(mylist)

Mais je veux sortir dans un CSV et avoir des délimiteurs autour des valeurs de la liste, par exemple

"value 1", "value 2", ... 

Je ne trouve pas de moyen simple d'inclure les délimiteurs dans la mise en forme, par exemple, j'ai essayé l' joininstruction. Comment puis-je faire ceci?

Fortilan
la source
Merci à tous, j'ai combiné les idées de quelques réponses pour résoudre ma question :) J'utilise maintenant le module csv pour écrire les [...] données directement dans un fichier import csv data = [...] myfile = open ( ..., 'wb') out = csv.writer (open ("myfile.csv", "w"), delimiter = ',', quoting = csv.QUOTE_ALL) out.writerow (data) fonctionne bien, je construis mes données [] en récupérant des données dans une feuille de calcul en utilisant xlrd et le module csv les écrit dans un fichier avec les bons délimiteurs tout est bon :) ty all again
Fortilan
Une approche plus récente pourrait être d'utiliser des pandas
Richard
Utilisateurs de Python 3.4, cela a fonctionné le mieux pour moi: stackoverflow.com/questions/25022677/…
Leigh

Réponses:

254
import csv

with open(..., 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)

Edit: cela ne fonctionne qu'avec python 2.x.

Pour le faire fonctionner avec python 3.x remplacer wbpar w( voir cette réponse SO )

with open(..., 'w', newline='') as myfile:
     wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
     wr.writerow(mylist)
Alex Martelli
la source
11
Notez que le csvmodule dans 2.x ne gère pas correctement les unicodes; voir la documentation du module pour des exemples sur la façon de gérer cela. docs.python.org/library/csv.html
Ignacio Vazquez-Abrams
14
vous pouvez également utiliser wr.writerows (list)
tovmeod
4
Writerows semble diviser chaque élément de la liste en colonnes si chaque élément est également une liste. Ceci est très pratique pour générer des tableaux.
whatnick
6
Cela ne fonctionne pas avec python 3.4. Je reçois TypeError: 'str' does not support the buffer interface.
botchniaque
1
Pour Python 2, utilisez 'w'comme ici: stackoverflow.com/questions/34283178/…
banan3'14
106

Voici une version sécurisée d'Alex Martelli:

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)
Cristian Garcia
la source
3
plus 1 pour l'utilisation with, en s'assurant que le fichier est fermé une fois terminé
BoltzmannBrain
Si j'utilise ceci dans une boucle for, le bloc with entier doit-il être imbriqué sous la boucle for? Ou serait-il plus efficace de n'avoir wr.writerow(my_list)qu'à l'intérieur de la boucle?
crypdick
1
@crypdick vous ne devriez certainement pas mettre le bloc entier dans la boucle. Ouvrez le fichier, puis écrivez chaque ligne dans une boucle. Il n'est pas nécessaire d'ouvrir le fichier n fois pour écrire n lignes.
Greg Kaleka
Si vous écrivez des objets de chaîne dans un fichier, suggérez d'utiliser «wt» lors de l'ouverture du fichier pour éviter TypeError: un objet de type octets est requis, pas «str».
don_Gunner94
41

Pour une autre approche, vous pouvez utiliser DataFrame dans les pandas : et il peut facilement vider les données en csv, tout comme le code ci-dessous:

import pandas
df = pandas.DataFrame(data={"col1": list_1, "col2": list_2})
df.to_csv("./file.csv", sep=',',index=False)
Qy Zuo
la source
1
Merci pour cet extrait de code, qui peut fournir une aide immédiate. Une explication appropriée améliorerait considérablement sa valeur éducative en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec des questions similaires, mais pas identiques. Veuillez modifier votre réponse pour ajouter une explication et donner une indication des limitations et hypothèses applicables.
Toby Speight
5
Aussi pour que cela fonctionne, les listes doivent avoir la même longueur, sinon vous obtiendrez une ValueError (pandas v 0.22.0)
cheevahagadog
32

La meilleure option que j'ai trouvée était d'utiliser le savetxtdu numpymodule :

import numpy as np
np.savetxt("file_name.csv", data1, delimiter=",", fmt='%s', header=header)

Au cas où vous auriez plusieurs listes à empiler

np.savetxt("file_name.csv", np.column_stack((data1, data2)), delimiter=",", fmt='%s', header=header)
tokenizer_fsj
la source
8
C'est bon pour le travail numérique, mais cela ne fonctionnera pas avec des chaînes dans la liste.
Ricardo Cruz
12

Utilisez le csvmodule de python pour lire et écrire des fichiers délimités par des virgules ou des tabulations. Le module csv est préféré car il vous donne un bon contrôle sur les citations.

Par exemple, voici l'exemple travaillé pour vous:

import csv
data = ["value %d" % i for i in range(1,4)]

out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL)
out.writerow(data)

Produit:

"value 1","value 2","value 3"
vy32
la source
4
Produit un fichier vide pour moi
caspii
La première exécution est vide et vous ne pouvez pas non plus la supprimer, car elle est ensuite ouverte en python. Deuxième exécution (ou plus précisément: out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL))remplit les données, peu importe si vous mettez open("myfile.csv","w")ou un nouveau fichier open("myfile2.csv","w"). On dirait que l'objet out ne peut pas traiter l'objet fichier créé lors de l'exécution, mais stocke le processus de sortie comme une tâche. En d'autres termes: l'objet out stocke l'objet fichier lors de la première exécution mais n'écrit que lorsque l'objet fichier existe déjà! Voir la bonne solution ci-dessous @Saurabh Adhikary
Lorenz
7

Vous pouvez utiliser la méthode string.join dans ce cas.

Divisez en quelques lignes pour plus de clarté - voici une session interactive

>>> a = ['a','b','c']
>>> first = '", "'.join(a)
>>> second = '"%s"' % first
>>> print second
"a", "b", "c"

Ou en une seule ligne

>>> print ('"%s"') % '", "'.join(a)
"a", "b", "c"

Cependant, vous pouvez avoir un problème si vos chaînes ont des guillemets incorporés. Si tel est le cas, vous devrez décider comment leur échapper.

Le module CSV peut s'occuper de tout cela pour vous, vous permettant de choisir entre différentes options de devis (tous les champs, uniquement les champs avec guillemets et séparateurs, uniquement les champs non numériques, etc.) et comment esacper les caractères de contrôle (guillemets doubles, ou chaînes échappées). Si vos valeurs sont simples, string.join sera probablement OK mais si vous devez gérer beaucoup de cas extrêmes, utilisez le module disponible.

Robert Christie
la source
3

Cette solution semble folle, mais fonctionne bien comme du miel

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL,delimiter='\n')
    wr.writerow(mylist)

Le fichier est en cours d'écriture par csvwriter donc les propriétés csv sont conservées, c'est-à-dire séparées par des virgules. Le délimiteur aide dans la partie principale en déplaçant les éléments de la liste à la ligne suivante, à chaque fois.

Saurabh Adhikary
la source
1
Si petit et si rapide
Ian Samz
1
fonctionne, et si vous avez une liste imbriquée, en développant l'exemple de @ vy32, vous avez:data = [["value %d" % i, "value %d" % (i+1)] for i in range(1,4)] with open("myfile.txt","w") as f: out = csv.writer(f, quoting=csv.QUOTE_ALL, delimiter='\n') out.writerow([';'.join(x) for x in data])
Lorenz
ça a vraiment l'air fou? Je pense que ça sonne parfaitement bien
Stephanie Owen
3

Pour créer et écrire dans un fichier csv

L'exemple ci-dessous illustre la création et l'écriture d'un fichier csv. pour créer un écrivain de fichier dynamique, nous devons importer un package d' importation csv , puis créer une instance du fichier avec la référence de fichier Ex: - avec open ("D: \ sample.csv", "w", newline = "" ) en tant que file_writer

ici si le fichier n'existe pas avec le répertoire de fichiers mentionné, python créera un même fichier dans le répertoire spécifié, et "w" représente l'écriture, si vous voulez lire un fichier, remplacez "w" par "r" ou ajouter au fichier existant puis "a". newline = "" spécifie qu'il supprime une ligne vide supplémentaire à chaque fois que vous créez une ligne afin d'éliminer la ligne vide, nous utilisons newline = "", créez des noms de champs (noms de colonnes) en utilisant une liste comme fields = ["Names", "Age "," Class "] , puis appliquez à l'instance de writer comme writer = csv.DictWriter (file_writer, fieldnames = fields) ici en utilisant Dictionary writer et en attribuant des noms de colonne, pour écrire les noms de colonne dans csv, nous utilisons writer.writeheader () , tandis que l'écriture des valeurs de fichier doit être transmise à l'aide de la méthode du dictionnaire, ici la clé est le nom de la colonne et la valeur est votre valeur de clé respective

import csv 

with open("D:\\sample.csv","w",newline="") as file_writer:

   fields=["Names","Age","Class"]

   writer=csv.DictWriter(file_writer,fieldnames=fields)

   writer.writeheader()

   writer.writerow({"Names":"John","Age":21,"Class":"12A"})
prasanna kumar
la source
2

Cahier Jupyter

Disons que votre liste est A

Ensuite, vous pouvez coder l'annonce suivante, vous l'aurez sous forme de fichier csv (colonnes uniquement!)

R="\n".join(A)
f = open('Columns.csv','w')
f.write(R)
f.close()
rsc05
la source
1

vous devriez utiliser le module CSV à coup sûr, mais il y a de fortes chances que vous deviez écrire unicode. Pour ceux qui ont besoin d'écrire unicode, voici la classe de la page d'exemple, que vous pouvez utiliser comme module util:

import csv, codecs, cStringIO

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

def __iter__(self):
    return self

def next(self):
    return self.reader.next().encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
    f = UTF8Recoder(f, encoding)
    self.reader = csv.reader(f, dialect=dialect, **kwds)

def next(self):
    row = self.reader.next()
    return [unicode(s, "utf-8") for s in row]

def __iter__(self):
    return self

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
"""

def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
    # Redirect output to a queue
    self.queue = cStringIO.StringIO()
    self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
    self.stream = f
    self.encoder = codecs.getincrementalencoder(encoding)()

def writerow(self, row):
    self.writer.writerow([s.encode("utf-8") for s in row])
    # Fetch UTF-8 output from the queue ...
    data = self.queue.getvalue()
    data = data.decode("utf-8")
    # ... and reencode it into the target encoding
    data = self.encoder.encode(data)
    # write to the target stream
    self.stream.write(data)
    # empty queue
    self.queue.truncate(0)

def writerows(self, rows):
    for row in rows:
        self.writerow(row)
kommradHomer
la source
1

Voici une autre solution qui ne nécessite pas le csvmodule.

print ', '.join(['"'+i+'"' for i in myList])

Exemple :

>>> myList = [u'value 1', u'value 2', u'value 3']
>>> print ', '.join(['"'+i+'"' for i in myList])
"value 1", "value 2", "value 3"

Cependant, si la liste initiale en contient ", ils ne seront pas échappés. Si c'est nécessaire, il est possible d'appeler une fonction pour l'échapper comme ça:

print ', '.join(['"'+myFunction(i)+'"' for i in myList])
Richard
la source