使用Python将CSV变量内容转换为JSON变量内容

时间:2014-05-28 08:45:31

标签: python json csv

我是Python的新手,我正在尝试转换包含JSON格式的CSV数据的变量。我尝试了这个,但是,如你所见,结果不是预期的结果:

>>> data = "a1;b1;c1\na2;b2;c2\na3;b3;c3"
>>>
>>> print data
a1;b1;c1
a2;b2;c2
a3;b3;c3
>>>
>>> fieldnames = ["col1","col2","col3"]
>>>
>>> csv_reader = csv.DictReader(data,fieldnames)
>>>
>>> json.dumps([r for r in csv_reader])
[{"col2": null, "col3": null, "col1": "a"}, {"col2": null, "col3": null, "col1": "1"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "b"}, {"col2": null, "col3": null, "col1": "1"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "c"}, {"col2": null, "col3": null, "col1": "1"}, {"col2": null, "col3": null, "col1": "a"}, {"col2": null, "col3": null, "col1": "2"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "b"}, {"col2": null, "col3": null, "col1": "2"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "c"}, {"col2": null, "col3": null, "col1": "2"}, {"col2": null, "col3": null, "col1": "a"}, {"col2": null, "col3": null, "col1": "3"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "b"}, {"col2": null, "col3": null, "col1": "3"}, {"col2": null, "col3": null, "col1": ";"}, {"col2": null, "col3": null, "col1": "c"}, {"col2": null, "col3": null, "col1": "3"}]'

如何让我的简单程序将变量行读取到行?

1 个答案:

答案 0 :(得分:2)

这里有两个问题。

首先,csv.DictReader不对字符串进行操作。相反,您应该传递iterator

这里有两个选项:

  • 将您的字符串转换为类似文件的对象(实现.read等方法的对象)。
  • 将您的字符串转换为列表(这是一个迭代器)。您可以使用.splitlines()执行此操作。对于这个建议的评价归功于评论中的Martijn Pieters。

您可以使用StringIO.StringIO类将字符串转换为类文件对象(请注意,在Python 3中,这是io.StringIO):

import StringIO
import csv

data = "a1;b1;c1\na2;b2;c2\na3;b3;c3"
fobj = StringIO.StringIO(data)

要将字符串转换为列表,只需执行:data.splitlines()


其次,你的csv文件是;分隔的,所以解析它不会起作用,除非你告诉csv模块期望它:

csv.register_dialect('semi', delimiter=';')

然后,你可以做你的事:

json.dumps(list(csv.DictReader(fobj, fieldnames, dialect='semi')))

你会得到:

[
    {
        "col2": "b1", 
        "col3": "c1", 
        "col1": "a1"
    }, 
    {
        "col2": "b2", 
        "col3": "c2", 
        "col1": "a2"
    }, 
    {
        "col2": "b3", 
        "col3": "c3", 
        "col1": "a3"
    }
]

注意,您无法多次从StringIO对象阅读,因此如果您尝试将其多次传递到csv.DictReader,则您无法获得你期待什么。你可以"倒带" StringIO对象使用:fobj.seek(0)