Python - 组合n个不同的json文件/字典(n可能会有所不同)

时间:2017-01-03 05:55:27

标签: python json dictionary dictionary-comprehension

我尝试使用问题中的关键字搜索此特定问题,但无法找到一个好的解决方案。

假设我有一个JSON文件列表(假设顶层始终是字典):

"../data/Flickr_EXIF_0.json",
"../data/Flickr_EXIF_150.json",
"../data/Flickr_EXIF_300.json",
"../data/Flickr_EXIF_450.json",

问题是将所有json文件合并/合并到一个文件中。

考虑到我们知道合并了多少个JSON文件,这样做当然很简单,

with open("../data/Flickr_EXIF_0.json", "r") as jFl:
    obj1 = json.load(jFl)

with open("../data/Flickr_EXIF_150.json", "r") as jFl:
    obj2 = json.load(jFl) 

with open("../data/Flickr_EXIF_300.json", "r") as jFl:
    obj3 = json.load(jFl) 

with open("../data/Flickr_EXIF_450.json", "r") as jFl:
    obj4 = json.load(jFl) 

d = {**obj1, **obj2, **obj3, **obj4}

但是你会怎么说写一个可以组合未知数量的JSON 的函数。我正在寻找一种pythonic解决方案。

这是我的部分解决方案,会引发错误:

def appendJSON(*inpFl):
    flObjs = []
    for fl in inpFl:
        with open(fl, "r") as jFl:
            flObjs.append(json.load(jFl))

    # something smart here! 
    itemsList = [list(objs.items()) for objs in flObjs]

    return dict(itemsList)

错误:

  

ValueError Traceback(最近一次调用   最后)in()        20" ../ data / Flickr_EXIF_1350.json",        21" ../ data / Flickr_EXIF_1500.json",   ---> 22" ../ data / Flickr_EXIF_1650.json")

     

in appendJSON(* inpFl)         7 itemsList = [objs.items()for fljbs中的objs]         8   ----> 9返回dict(itemsList)        10        11 objs = appendJSON(" ../ data / Flickr_EXIF_0.json",

     

ValueError:字典更新序列元素#0的长度为150; 2是   需要

itemsList的示例调试值:

[[('5822864395',
   {'date': '2010-06-10 14:48:25',
    'height': 2592,
    'lat': 0.0,
    'long': 0.0,
    'orientation': 0,
    'width': 2818}),
   ('1458886548',
   {'date': '2007-09-22 02:59:20',
    'height': 768,
    'lat': 39.145372,
    'long': -84.508981,
    'orientation': 0,
    'width': 1024})]]

替代解决方案,

def appendJSON(*inpFl):
    flObjs = []
    for fl in inpFl:
        with open(fl, "r") as jFl:
            flObjs.append(json.load(jFl))

    for i in range(1,len(flObjs)):
        flObjs[0].update(flObjs[i])

    return flObjs[0]

2 个答案:

答案 0 :(得分:2)

我首先会制作一个通用解决方案,然后根据JSON文件的顶级类型(即所有对象/字典或所有数组/列表)进行选择性优化。

如果您在加载(dict,list,value)后混合使用顶级类型,则无论如何都无法将它们组合在一起。如果每个加载的数据都是dict,或者每个加载的数据都是列表,则只能组合它们。如果您有一个组合,或者如果您在顶层有一个或多个值,则无法合并。

通用方法是创建一个空列表,并.append()json.load()加载到其中的数据,同时跟踪有,dict,列表或值:

def combine(json_file_names):
    combined = []
    have_dict = False
    have_list = False
    for file_name in json_file_names:
        data = json.load(file_name)
        combined.append(data)
        if isinstance(data, dict):
            have_dict = True
        elif isinstance(data, list):
            have_list = True
        else:
            have_list = have_dict = True

    # if have_list and have_dict have the same value, either there is nothing 
    # loaded or it's a mixed bag. In both cases you can't do anything
    if have_list == have_dict:  
        return combined
    if have_list:
        tmp = []
        for elem in combined:
            tmp.extend(elem)
    else:  # have_dict
        tmp = {}
        for elem in combined:
            tmp.update(elem)
    return tmp

请注意,在梳理all-top-level-dicts时,您会覆盖以前加载的数据中的键值对。

答案 1 :(得分:0)

由于json很容易转换为Python dict,所以你需要做的就是将所有json文件读入字典,合并所有字典,转换为json并将其保存到文件中。