将数据附加到现有的json文件

时间:2017-12-10 14:06:52

标签: json python-2.7 csv

感谢有人能指出我在这里的正确方向,对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"
    }  
]

实现这一目标的最佳方法是保持输出顺序。 感谢任何指导。

1 个答案:

答案 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等可选顺序。

相关问题