151 votes

Comment écrire des données au format CSV sous forme de chaîne (et non de fichier) ?

Je veux lancer des données comme [1,2,'a','He said "what do you mean?"'] en une chaîne de caractères au format CSV.

Normalement, on utilise csv.writer() pour cela, parce qu'il gère tous les cas particuliers (échappement des virgules, échappement des guillemets, dialectes de CSV, etc. csv.writer() s'attend à ce que la sortie se fasse vers un objet fichier, et non vers une chaîne de caractères.

Ma solution actuelle est cette fonction un peu bricolée :

def CSV_String_Writeline(data):
    class Dummy_Writer:
        def write(self,instring):
            self.outstring = instring.strip("\r\n")
    dw = Dummy_Writer()
    csv_w = csv.writer( dw )
    csv_w.writerow(data)
    return dw.outstring

Quelqu'un peut-il proposer une solution plus élégante qui gère bien les cas limites ?

Edit : Voici comment j'ai fini par le faire :

def csv2string(data):
    si = StringIO.StringIO()
    cw = csv.writer(si)
    cw.writerow(data)
    return si.getvalue().strip('\r\n')

223voto

Tim Pietzcker Points 146308

Dans Python 3 :

>>> import io
>>> import csv
>>> output = io.StringIO()
>>> csvdata = [1,2,'a','He said "what do you mean?"',"Whoa!\nNewlines!"]
>>> writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC)
>>> writer.writerow(csvdata)
59
>>> output.getvalue()
'1,2,"a","He said ""what do you mean?""","Whoa!\nNewlines!"\r\n'

Certains détails doivent être modifiés un peu pour Python 2 :

>>> output = io.BytesIO()
>>> writer = csv.writer(output)
>>> writer.writerow(csvdata)
57L
>>> output.getvalue()
'1,2,a,"He said ""what do you mean?""","Whoa!\nNewlines!"\r\n'

73voto

NPE Points 169956

Vous pourriez utiliser StringIO au lieu de votre propre Dummy_Writer :

Ce module implémente une classe de type fichier, StringIO qui lit et écrit un tampon de chaîne (également connu sous le nom de fichiers mémoire).

Il y a également cStringIO qui est une version plus rapide du StringIO classe.

6voto

user2099484 Points 1653

J'ai trouvé les réponses, dans l'ensemble, un peu confuses. Pour Python 2, cette utilisation a fonctionné pour moi :

import csv, io

def csv2string(data):
    si = io.BytesIO()
    cw = csv.writer(si)
    cw.writerow(data)
    return si.getvalue().strip('\r\n')

data=[1,2,'a','He said "what do you mean?"']
print csv2string(data)

6voto

Car je l'utilise souvent pour diffuser les résultats de manière asynchrone à partir de sanic à l'utilisateur en tant que données csv, j'ai écrit le snippet suivant pour Python 3 .

Ce snippet vous permet de réutiliser le même tampon StringIo à l'infini.

import csv
from io import StringIO

class ArgsToCsv:
    def __init__(self, seperator=","):
        self.seperator = seperator
        self.buffer = StringIO()
        self.writer = csv.writer(self.buffer)

    def stringify(self, *args):
        self.writer.writerow(args)
        value = self.buffer.getvalue().strip("\r\n")
        self.buffer.seek(0)
        self.buffer.truncate(0)
        return value + "\n"

exemple :

csv_formatter = ArgsToCsv()

output += csv_formatter.stringify(
    10,
    """
    lol i have some pretty
    "freaky"
    strings right here \' yo!
    """,
    [10, 20, 30],
)

Pour en savoir plus sur l'utilisation, consultez le gist de github : source et test

-1voto

bjelli Points 3569

Voici la version qui fonctionne pour utf-8. csvline2string pour une seule ligne, sans saut de ligne à la fin, csv2string pour plusieurs lignes, avec saut de ligne :

import csv, io

def csvline2string(one_line_of_data):
    si = BytesIO.StringIO()
    cw = csv.writer(si)
    cw.writerow(one_line_of_data)
    return si.getvalue().strip('\r\n')

def csv2string(data):
    si = BytesIO.StringIO()
    cw = csv.writer(si)
    for one_line_of_data in data:
        cw.writerow(one_line_of_data)
    return si.getvalue()

Prograide.com

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.

Powered by:

X