【问题标题】:Python csv to json column orderPython csv到json列顺序
【发布时间】:2015-08-22 17:32:59
【问题描述】:

基本的 Python csv 到 json 脚本在最终的 JSON 中混合列顺序。知道为什么吗?

test.csv

animal,age,count,legs
dogs,3,5,4
cats,6,4,4
birds,2,1,2

脚本

import csv
import json

csvfile = open('test.csv', 'r')
jsonfile = open('test.json', 'w')

reader = csv.DictReader( csvfile)

jsonfile.write('[')
for row in reader:
    json.dump(row, jsonfile)
    jsonfile.write(',\n')
jsonfile.write(']')

test.json

[{"count": "5", "age": "3", "legs": "4", "animal": "dogs"},
{"count": "4", "age": "6", "legs": "4", "animal": "cats"},
{"count": "1", "age": "2", "legs": "2", "animal": "birds"},
]

【问题讨论】:

  • 您可以使用它来获取有序字典pymotw.com/2/collections/ordereddict.html
  • json 未排序。也不是python dict。
  • @njzk2 就Object.keys(json[0]) 而言
  • @geotheory 这只是一个巧合。不要依赖那个。 (您还会注意到小整数在set 中排序,但这并不意味着其他键也会如此)

标签: python json csv


【解决方案1】:

因为字典没有任何顺序感,所以期望字典是任意顺序的。

如果您必须保留顺序(理想情况下您不应该这样做),您需要使用简单的 csv 阅读器读取每一行,然后创建 collection.OrderedDict 对象,这些对象确实存储了添加键的顺序.示例 -

from collections import OrderedDict
import csv
with open('test.csv','r') as f:
    reader = csv.reader(f)
    headerlist = next(reader)
    csvlist = []
    for row in reader:
            d = OrderedDict()
            for i, x in enumerate(row):
                    d[headerlist[i]] = x
            csvlist.append(d)

import json
with open('test.json','w') as f:
    json.dump(csvlist,f)

请注意,如果使用此 JSON 的解析器不以同样的方式尊重顺序,这仍然是无用的。


示例/演示 -

以我的test.csv 为-

animal,age,count,legs
dogs,3,5,4
cats,6,4,4
birds,2,1,2

test.json 看起来像 -

[{"animal": "dogs", "age": "3", "count": "5", "legs": "4"}, 
{"animal": "cats", "age": "6", "count": "4", "legs": "4"}, 
{"animal": "birds", "age": "2", "count": "1", "legs": "2"}]

【讨论】:

  • 但是为什么每次都以相同的顺序给出行
  • @VigneshKalai,字典的顺序不是随机的,只是不符合他们期望的顺序。
  • @JasonSperske 这是有道理的,但是字典中有某种排序
  • VigneshKalai,因为行会记住它的项目,但字典不会,因为它依赖于键值结构。
  • 这是没用的。即使 json 文件以某种顺序呈现数据,也不能保证解析器会尊重它。
【解决方案2】:

在 Anand 的回答中,您只是暂时解决了问题。 JSON 文件可能以正确的顺序输出,但是您可以在另一个位置(例如浏览器或另一个 Python 进程)读取此数据,并且当它在此文件中读取时,将不会保留顺序!

如果您想保证数据源和目标之间的顺序,您将需要使用列表列表。

您可以执行以下操作来保持顺序:

import csv 
import json

lst = []
csvfile = open('test.csv', 'r')
jsonfile = open('test.json', 'w')
first_line = next(csvfile).split(',')

csvfile.seek(0) # we peeked at the first_line, lets reset back to beginning

reader = csv.DictReader(csvfile)

for row in reader:
    group = []
    for h in first_line:
        h = h.strip()
        group.append([h, row[h]])
    lst.append(group)

jsonfile.write(json.dumps(lst))

输出:

[[["animal", "dogs"], ["age", "3"], ["count", "5"], ["legs", "4"]], [["animal", "cats"], ["age", "6"], ["count", "4"], ["legs", "4"]], [["animal", "birds"], ["age", "2"], ["count", "1"], ["legs", "2"]]]

【讨论】:

  • 注明。感谢您的提示
猜你喜欢
  • 2017-07-29
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 2015-06-09
  • 1970-01-01
  • 2016-04-19
相关资源
最近更新 更多