如何将数据作为字符串(而非文件)写入CSV格式?


119

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

通常会用到csv.writer()它,因为它处理所有疯狂的情况(逗号转义,引号转义,CSV方言等)。捕获的结果是csv.writer()期望输出到文件对象,而不是字符串。

我当前的解决方案是此功能有点怪异:

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

2
在Python 3中,StringIO()io库中。
阿里斯蒂德

Answers:


66

您可以使用StringIO而不是自己的Dummy_Writer

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

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


164

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

好的例子。:)作为旁注,在CSV文件中遇到换行符时的通常行为是什么?是否\n确定有数据的中间,但\r\n表示记录的末尾不管它在哪里出现?(假设您使用的平台是\r\n行终止器。)
Li-aung Yip 2012年

2
应该为output = StringIO.StringIO()io.StringIO()将引发TypeError:预期的字符串参数,为'str'。
马波尼2012年

2
@Marboni:StringIO在Python 3中消失了(这是我的解决方案所写的内容),尽管writer.writerow(...)在行(unicode argument expected, got 'str')中确实出现TypeError,但我无法在Python 2.7.3中重现该错误。会调查一下。
Tim Pietzcker 2012年

1
@Marboni:感谢您的单挑:我 StackOverflow的帮助下发现了问题。在Python 2中,您需要io.BytesIO()而不是io.StringIO()
Tim Pietzcker 2012年

1
@Marboni:在Python 2.7.9中,它与StringIO.StringIO()或io.BytesIO()一起使用。
2015年

6

我发现答案总的来说有点令人困惑。对于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)

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 gist上查看更多用法:源代码和测试



-1

这是适用于utf-8的版本。csvline2string仅用于一行,末尾没有换行符,csv2string用于多行,具有换行符:

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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.