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

使用Python将CSV变量内容转换为JSON变量内容,python,json,csv,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"] >>>

我是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"}]'

如何使我的简单程序逐行读取变量?

这里有两个问题

首先,
csv.DictReader
不会对字符串进行操作。相反,你应该通过考试

这里有两个选项:

  • 将字符串转换为类似文件的对象(实现
    .read
    等方法的对象)
  • 将字符串转换为列表(它是迭代器)。您可以使用
    .splitlines()
    完成此操作。这项建议的功劳归于评论中的Martijn Pieters
您可以使用
StringIO.StringIO
类将字符串转换为类似文件的对象(注意,在Python 3中,这是
io.StringIO
):

要将字符串转换为列表,只需执行以下操作:
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
,您将无法获得预期的结果。您可以使用:
fobj.seek(0)

csv.DictReader()
操作iterables,“倒带”StringIO对象;如果你真的想要的话,你可以传递一个列表<例如,code>data.splitlines()
就可以了。接下来,您也不必注册方言
csv.reader()
csv.DictReader()
也接受
分隔符
参数
csv.DictReader(data.splitlines(),fieldnames,delimiter=';')
对于一次性操作来说要方便得多。@MartijnPieters这的确是一个很好的观察结果。请注意,非常感谢!我有很多东西要用Python学习,希望那里有好老师;)
[
    {
        "col2": "b1", 
        "col3": "c1", 
        "col1": "a1"
    }, 
    {
        "col2": "b2", 
        "col3": "c2", 
        "col1": "a2"
    }, 
    {
        "col2": "b3", 
        "col3": "c3", 
        "col1": "a3"
    }
]