【问题标题】:How to deepmerge dicts/list for a json in python如何在python中为json深度合并dicts/list
【发布时间】:2020-11-12 09:24:29
【问题描述】:

我正在尝试对列表进行深度合并以获取特定的 json。

我想要实现的是这种格式(元素的顺序无关):

{
 "report": {
    "context": [{
            "report_id": [
                "Report ID 30"
            ],
            "status": [
                "Status 7"
            ],
            "fallzahl": [
                "Fallzahl 52"
            ],
            "izahl": [
                "IZahl 20"
            ]
        }
    ],
    "körpergewicht": [{
            "any_event_en": [{
                    "gewicht": [{
                            "|magnitude": 185.44,
                            "|unit": "kg"
                        }
                    ],
                    "kommentar": [
                        "Kommentar 94"
                    ],
                    "bekleidung": [{
                            "|code": "at0011"
                        }
                    ]
                   
                }
            ]
        }
    ]
}

} 我尝试对字典和列表进行深度合并以实现这种特定格式。我的基线是一些字典:

{'körpergewicht': [{'any_event_en': [{'gewicht': [{'|magnitude': '100', '|unit': 'kg'}]}]}]}

{'körpergewicht': [{'any_event_en': [{'bekleidung': [{'|code': 'at0013'}]}]}]}

{'körpergewicht': [{'any_event_en': [{'kommentar': ['none']}]}]}

{'context': [{'status': ['fatty']}]}

{'context': [{'fallzahl': ['123']}]}

{'context': [{'report_id': ['123']}]}

{'context': [{'izahl': ['123']}]}

我试图做的是跟随我有一个名为 tmp_dict 的字典,因为我在循环时持有一个基线字典。所谓的 collect_dict 是我尝试合并基线字典的字典。 element 保存我当前的基线字典。

if (index == (len(element)-1)): #when the baseline dict is traversed completely
   if tmp_dict:
      first_key_of_tmp_dict=list(tmp_dict.keys())[0]
      if not (first_key_of_tmp_dict in collect_dict):
         collect_dict.update(tmp_dict)
      else:
         merge(tmp_dict,collect_dict)
   else:
      collect_dict.update(tmp_dict)

而且我还写了一个合并方法:

    def merge(tmp_dict,collect_dict):
        first_common_key_of_dicts=list(tmp_dict.keys())[0]
        second_depth_key_of_tmp_dict=list(tmp_dict[first_common_key_of_dicts][0].keys())[0]
        second_depth_tmp_dict=tmp_dict[first_common_key_of_dicts][0]
        second_depth_key_of_coll_dict=collect_dict[first_common_key_of_dicts][0]
        if not second_depth_key_of_tmp_dict in second_depth_key_of_coll_dict:
            collect_dict.update(second_depth_tmp_dict)
        else:
            merge(second_depth_tmp_dict,second_depth_key_of_coll_dict)

我想出的方向正确,但远未达到我想要的输出:

{"report": {
                "k\u00f6rpergewicht": [{
                        "any_event_en": [{
                                "kommentar": ["none"]
                            }
                        ],
                        "bekleidung": [{
                                "|code": "at0013"
                            }
                        ],
                        "gewicht": [{
                                "|magnitude": "100",
                                "|unit": "kg"
                            }
                        ]
                    }
                ],
                "context": [{
                        "fallzahl": ["234"]
                    }
                ],
                "report_id": ["234"],
                "status": ["s"],
                "izahl": ["234"]
            }
}

使用另一组输入:

{'atemfrequenz': {'context': [{'status': [{'|code': 'at0012'}]}]}},
{'atemfrequenz': {'context': [{'kategorie': ['Kategorie']}]}},
{'atemfrequenz': {'atemfrequenz': [{'messwert': [{'|magnitude': '123', '|unit': 'min'}]}]}}

我想实现以下输出:

"atemfrequenz": {
    "context": [
      {
        "status": [
          {
            "|code": "at0012"
          }
        ],
        "kategorie": [
          "Kategorie"
        ]
      }
    ],
    "atemfrequenz": [
      {
        "messwert": [
          {
            "|magnitude": 123,
            "|unit": "/min"
          }
        ]
      }
    ]
  }

【问题讨论】:

    标签: python json dictionary merge


    【解决方案1】:

    这段代码应该得到正确的答案。我删除了特殊字符 (ö) 以防止出现错误。

    dd = [
    {'korpergewicht': [{'any_event_en': [{'gewicht': [{'|magnitude': '100', '|unit': 'kg'}]}]}] },
    {'korpergewicht': [{'any_event_en': [{'bekleidung': [{'|code': 'at0013'}]}]}]},
    {'korpergewicht': [{'any_event_en': [{'kommentar': ['none']}]}]},
    {'context': [{'status': ['fatty']}]},
    {'context': [{'fallzahl': ['123']}]},
    {'context': [{'report_id': ['123']}]},
    {'context': [{'izahl': ['123']}]}
    ]
    
    
    def merge(d):
       if (type(d) != type([])): return d
       if (type(list(d[0].values())[0])) == type(""): return d
       keys = list(set(list(k.keys())[0] for k in d))
       lst = [{k:[]} for k in keys]
       for e in lst:
           for k in d:
               if (list(e.keys())[0] == list(k.keys())[0]):
                   e[list(e.keys())[0]] += k[list(k.keys())[0]]
       for e in lst:
           if (type(e[list(e.keys())[0]][0]) == type({})):
               e[list(e.keys())[0]] = merge(e[list(e.keys())[0]]) 
           for i in lst[1:]: lst[0].update(i)
       lst2 = []  # return list of single dictionary
       lst2.append(lst[0])
       return lst2
    
    dx = merge(dd)
    dx = {'report': dx[0]} # no list at lowest level
    print(dx)
    

    输出(格式化)

    {'report': {
         'korpergewicht': [{
              'any_event_en': [{
                    'kommentar': ['none'], 
                    'bekleidung': [{'|code': 'at0013'}], 
                    'gewicht': [{'|magnitude': '100', '|unit': 'kg'}]}]}], 
          'context': [{
              'report_id': ['123'], 
              'izahl': ['123'], 
              'fallzahl': ['123'], 
              'status': ['fatty']}]}}
    

    关于提供的第二个数据集,数据需要结构化以匹配之前的数据集。

    这个数据集工作正常:

    dd = [
    {'atemfrequenz': [{'context': [{'status': [{'|code': 'at0012'}]}]}]}, 
    {'atemfrequenz': [{'context': [{'kategorie': ['Kategorie']}]}]}, 
    {'atemfrequenz': [{'atemfrequenz': [{'messwert': [{'|magnitude': '123', '|unit': 'min'}]}]}]} 
    ] 
    

    输出(格式化)

    {'report': {
        'atemfrequenz': [{
             'atemfrequenz': [{
                  'messwert': [{'|magnitude': '123', '|unit': 'min'}]}], 
        'context': [{
             'kategorie': ['Kategorie'], 
             'status': [{'|code': 'at0012'}]}]}]}}
    

    【讨论】:

    • 在您的回答中,这些行是字典,但它们应该是一个字典,而不是每个字典,如下所示: "körpergewicht": [{ "any_event_en": [{ "gewicht": [{ "|magnitude": 185.44, "|unit": "kg" } ], "kommentar": [ "Kommentar 94" ], "bekleidung": [{ "|code": "at0011" } ]
    • 在我使用这些输入之前,您的代码对我来说运行良好:'[{'atemfrequenz': {'context': [{'status': [{'|code': 'at0012'}] }]}}, {'atemfrequenz': {'context': [{'kategorie': ['Kategorie']}]}}, {'atemfrequenz': {'atemfrequenz': [{'messwert': [{' |magnitude': '123', '|unit': 'min'}]}]}}]',现在我在合并后得到这个 [{'atemfrequenz': ['context', 'context', 'atemfrequenz' ]}]
    • 如果你对数据结构做一个小改动,它就会正确处理。
    • 我不知道在哪里
    • 对我来说,您最近的更改无法正常工作,我更新了我的问题,以获得更好的概览。
    猜你喜欢
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2017-02-21
    • 2015-03-12
    相关资源
    最近更新 更多