如何将数据以CSV格式写入字符串(而不是文件)?

时间:2012-02-06 08:21:49

标签: python string csv

我想将[1,2,'a','He said "what do you mean?"']之类的数据转换为CSV格式的字符串。

通常人们会使用csv.writer(),因为它会处理所有疯狂的边缘情况(逗号转义,引用标记转义,CSV方言等)。问题是csv.writer()期望输出到文件对象,而不是字符串。

我目前的解决方案是这个有点hacky功能:

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

任何人都可以提供更优雅的解决方案,仍能很好地处理边缘情况吗?

编辑:这是我最终如何做到的:

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

7 个答案:

答案 0 :(得分:118)

在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'

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'

答案 1 :(得分:50)

您可以使用StringIO代替自己的Dummy_Writer

  

该模块实现了一个类文件类StringIO,它读写字符串缓冲区(也称为内存文件)。

还有cStringIO,这是StringIO类的更快版本。

答案 2 :(得分:5)

总而言之,我找到了答案,有点令人困惑。对于Python 2,这种用法对我有用:

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)

答案 3 :(得分:2)

因为我经常使用此代码将 sanic 的结果作为csv数据异步流回用户,所以我为 Python 3 编写了以下代码段。

该代码段可让您一次又一次地重复使用相同的StringIo缓冲区。


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"

示例:

csv_formatter = ArgsToCsv()

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

在github上查看更多用法:source and test

答案 4 :(得分:0)

这是适用于utf-8的版本。 csvline2string只有一行,最后没有换行符,csv2string为多行,有换行符:

1>------ Deploy started: Project: firstapp, Configuration: Debug Any CPU ------
1>Deployment of application to device failed.
1>Error: Value cannot be null.

答案 5 :(得分:0)

由于您的示例仅包含一行数据,因此您可以简单地使用

input = [1,2,'a','He said "what do you mean?"']
output = ",".join(str(x) for x in input)

很显然,如果输入数据具有更复杂的形式,例如字典或2d数组,则此简单答案将变得更加复杂。

答案 6 :(得分:-1)

import csv
from StringIO import StringIO
with open('file.csv') as file:
    file = file.read()

stream = StringIO(file)

csv_file = csv.DictReader(stream)