感谢有人能指出我在这里的正确方向,对python来说是新的:)
我有一个如下所示的json文件:
[
{
"user":"user5",
"games":"game1"
},
{
"user":"user6",
"games":"game2"
},
{
"user":"user5",
"games":"game3"
},
{
"user":"user6",
"games":"game4"
}
]
我有一个小的csv文件,如下所示:
module_a,module_b
10,20
15,16
1,11
2,6
我正在尝试将csv数据附加到上面提到的json中,所以看起来这样,按顺序保持顺序:
[
{
"user":"user5",
"module_a":"10",
"games":"game1",
"module_b":"20"
},
{
"user":"user6",
"module_a":"15",
"games":"game2",
"module_b":"16"
},
{
"user":"user5",
"module_a":"1",
"games":"game3",
"module_b":"11"
},
{
"user":"user6",
"module_a":"2",
"games":"game4",
"module_b":"6"
}
]
实现这一目标的最佳方法是保持输出顺序。 感谢任何指导。
答案 0 :(得分:0)
JSON specification没有规定顺序,并且它不会被任何JSON解析器强制执行(除非它是底层平台的默认操作模式)所以很长一段时间在处理JSON文件时保持顺序通常是没有意义的。引用:
对象是零个或多个名称/值的无序集合 对,其中名称是字符串,值是字符串,数字, boolean,null,object或array。
...
已经观察到JSON解析库在是否存在时会有所不同 不是它们使对象成员的排序对调用可见 软件。行为不依赖于成员的实现 排序将是可互操作的,因为它们不会 受到这些差异的影响。
话虽如此,如果你真的坚持订单,你可以将你的JSON解析为collections.OrderedDict
(并从中回写),这将允许你在保持整体订单的同时在特定地点注入数据。因此,首先将您的JSON加载为:
import json
from collections import OrderedDict
with open("input_file.json", "r") as f: # open the JSON file for reading
json_data = json.load(f, object_pairs_hook=OrderedDict) # read & parse it
现在你已经拥有了JSON,你可以继续加载你的CSV,因为与数据没什么关系,你可以立即将它应用到json_data
。有一点需要注意 - 由于CSV和JSON之间没有直接映射,因此必须将索引视为地图(即应用于第一个JSON元素的第一个CSV行等),因此我们将使用{ {1}}跟踪当前索引。还没有关于在何处插入单个值的信息,因此我们假设第一列在第一个JSON对象条目之后,第二列在第二个条目之后,依此类推,因为它们可以具有不同的长度,我们&# 39; ll使用enumerate()
来交错它们。所以:
itertools.izip_longest()
将我们的CSV数据很好地插入到import csv
from itertools import izip_longest # use zip_longest on Python 3.x
with open("input_file.csv", "rb") as f: # open the CSV file for reading
reader = csv.reader(f) # build a CSV reader
header = next(reader) # lets store the header so we can get the key values later
for index, row in enumerate(reader): # enumerate and iterate over the rest
if index >= len(json_data): # there are more CSV rows than we have elements in JSO
break
row = [(header[i], v) for i, v in enumerate(row)] # turn the row into element tuples
# since collections.OrderedDict doesn't support random access by index we'll have to
# rebuild it by mixing in the CSV elements with the existing JSON elements
# use json_data[i].items() on Python 3.x
data = (v for p in izip_longest(json_data[index].iteritems(), row) for v in p)
# then finally overwrite the current element in json_data with a new OrderedDict
json_data[index] = OrderedDict(data)
中,剩下的就是回写JSON(如果您愿意,可以覆盖原始文件):
json_data
这将产生您之后的结果。它甚至尊重CSV标头中的名称,因此您可以将其替换为with open("output_file.json", "w") as f: # open the output JSON file for writing
json.dump(json_data, f, indent=2) # finally, write back the modified JSON
和bob
,并将它们插入您的JSON中。如果您需要向JSON添加更多元素,甚至可以添加更多元素。
尽管如此,仅仅因为它可能,你真的不应该依赖于JSON的顺序。如果您之后是用户可读性,则有更合适的格式以及YAML等可选顺序。