如何将数据作为字符串(不是文件)写入 CSV 格式?
Posted
技术标签:
【中文标题】如何将数据作为字符串(不是文件)写入 CSV 格式?【英文标题】:How do I write data into CSV format as string (not file)? 【发布时间】:2012-02-27 18:18:29 【问题描述】:我想将[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')
【问题讨论】:
在 Python 3 中,StringIO()
在 io
库中。
因为 "\r" 和 "\n" 被认为是空白,你实际上可以只使用不带参数的 "strip":return si.getvalue().strip()
--除非出于某种原因你需要在结束。
【参考方案1】:
您可以使用StringIO
代替您自己的Dummy_Writer
:
这个模块实现了一个类似文件的类
StringIO
,它读取和写入一个字符串缓冲区(也称为内存文件)。
还有cStringIO
,它是StringIO
类的更快版本。
【讨论】:
cStringIO 自 python 3.0 起就消失了。请改用io.StringIO
【参考方案2】:
在 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'
【讨论】:
应该是output = StringIO.StringIO()
,io.StringIO()
会引发 TypeError: string argument expected, got 'str'。
@Marboni: StringIO 在 Python 3 中消失了(这是我的解决方案所用的),我无法在 Python 2.7.3 中重现该错误 - 尽管我在writer.writerow(...)
行 (unicode argument expected, got 'str'
)。将对此进行调查。
@Marboni:感谢您的提醒:我在 *** 的帮助下found the problem。在 Python 2 中,您需要 io.BytesIO()
而不是 io.StringIO()
。
@Marboni:在 Python 2.7.9 中,它适用于 StringIO.StringIO() 或 io.BytesIO()。
@nz_21:我刚刚重新测试了它——工作得很好。当然,第二个示例(为 Python 2 编写,如明确说明的那样)会抛出该错误。【参考方案3】:
这是适用于 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()
【讨论】:
【参考方案4】:import csv
from StringIO import StringIO
with open('file.csv') as file:
file = file.read()
stream = StringIO(file)
csv_file = csv.DictReader(stream)
【讨论】:
不鼓励仅使用代码的答案,您应该在答案中添加一些说明【参考方案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)
【讨论】:
【参考方案6】:由于我经常使用这种方法将结果从 sanic 异步传输回用户作为 csv 数据,因此我为 Python 3 编写了以下 sn-p。 p>
sn-p 让您可以反复重用相同的 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 上查看更多用法:source and test
【讨论】:
以上是关于如何将数据作为字符串(不是文件)写入 CSV 格式?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用Nodejs将数据作为文件夹中的文件名写入CSV文件