【问题标题】:How to merge nested dictionary having same keys in python如何在python中合并具有相同键的嵌套字典
【发布时间】:2021-07-23 23:36:49
【问题描述】:

我有这样的数据结构:

[ {'SNAPSHOT': {'SnapshotVersion': '304'}},

  {'SNAPSHOT': {'SnapshotCreationDate': '2015-06-21 17:33:41'}},


  {'CafeData': {'CafeVersion': '2807'}}, 

  {'CafeData': {'IsSoftwareOnly': '1'}}, 

  {'CafeData'{'IsPassportTCPIP': '1'}} 

  {'SNAPSHOT': {'SnapshotVersion': '777'}},

  {'SNAPSHOT': {'SnapshotCreationDate': '2017-07-27 17:37:47'}},]

输出应该是这样的:

 [ {'SNAPSHOT': {'SnapshotVersion': '304','SnapshotCreationDate': '2015-06-21 17:33:41'}},

   {'CafeData': {'CafeVersion': '2807','IsSoftwareOnly': '1','IsPassportTCPIP': '1'}} 
 
   {'SNAPSHOT': {'SnapshotVersion': '777','SnapshotCreationDate': '2017-07-27 17:37:47'}},
]

或者输出应该是这样的:

[ {'SNAPSHOT': {'SnapshotVersion': ['304','777'],
                'SnapshotCreationDate': ['2015-06-21 17:33:41','2017-07-27 17:37:47']}},

   {'CafeData': {'CafeVersion': '2807','IsSoftwareOnly': '1','IsPassportTCPIP': '1'}} 

]

【问题讨论】:

  • 您还没有在这里得到答案吗? stackoverflow.com/questions/67328076/…
  • @BuddyBobIII:原始问题中的要求更简单。他今天用这个新的变体编辑了这个问题,所以我让他创建一个单独的问题。
  • 不,这不一样,输出不一样。给出正确答案的人建议我创建一个新问题。
  • 好的,知道了!只是想知道您为什么两次发布相同的问题,谢谢您的澄清。
  • 你在第三个 CafeData 键中有错字。那么列表元素是具有单个键的字典和另一个字典的值?

标签: python python-3.x list dictionary


【解决方案1】:

可以使用 for 循环并跟踪合并的最后一个键。

from pprint import pprint

data = [
    {"SNAPSHOT": {"SnapshotVersion": "304"}},
    {"SNAPSHOT": {"SnapshotCreationDate": "2015-06-21 17:33:41"}},
    {"CafeData": {"CafeVersion": "2807"}},
    {"CafeData": {"IsSoftwareOnly": "1"}},
    {"CafeData": {"IsPassportTCPIP": "1"}},
    {"SNAPSHOT": {"SnapshotVersion": "777"}},
    {"SNAPSHOT": {"SnapshotCreationDate": "2017-07-27 17:37:47"}},
]

last_key = None
grouped = []
for value in data:
    # Easy way to get the key of a dict with one key
    curr_key = next(iter(value))
    # Decide if we should work on the next entry
    if last_key is None or curr_key != last_key:
        grouped.append(value)
    else:
        # update the last value in the group with the new data
        grouped[-1][curr_key].update(value[curr_key])
    # Move to the next item
    last_key = curr_key

pprint(grouped)
[{'SNAPSHOT': {'SnapshotCreationDate': '2015-06-21 17:33:41',
               'SnapshotVersion': '304'}},
 {'CafeData': {'CafeVersion': '2807',
               'IsPassportTCPIP': '1',
               'IsSoftwareOnly': '1'}},
 {'SNAPSHOT': {'SnapshotCreationDate': '2017-07-27 17:37:47',
               'SnapshotVersion': '777'}}]

选项 2 类似,但对于分组我只会使用 dict。在这种情况下,您不需要知道最后一个键。

如果嵌套字典中存在键冲突,您还需要对如何合并 vales 做出一些假设。

grouped = {}
for value in data:
    curr_key = next(iter(value))
    curr_value = value[curr_key]
    group = grouped.setdefault(curr_key, {})

    for sub_key, sub_value in curr_value.items():
        # check if you need to merge
        if sub_key in group:
            # If the key is already present, but is not a list, make it one
            if not isinstance(group[sub_key], list):
                group[sub_key] = [group[sub_key]]
            # Add the new value to the list
            group[sub_key].append(sub_value)
        else:
            # Otherwise just copy it over
            group[sub_key] = sub_value

pprint(grouped)
{'CafeData': {'CafeVersion': '2807',
              'IsPassportTCPIP': '1',
              'IsSoftwareOnly': '1'},
 'SNAPSHOT': {'SnapshotCreationDate': ['2015-06-21 17:33:41',
                                       '2017-07-27 17:37:47'],
              'SnapshotVersion': ['304', '777']}}

【讨论】:

    【解决方案2】:

    这是一个使用 [Python.Docs]: itertools.groupby(iterable, key=None) 的变体。

    code00.py

    #!/usr/bin/env python
    
    import sys
    import itertools as it
    from pprint import pprint as pp
    
    
    l = [
        {"SNAPSHOT": {"SnapshotVersion": "304"}},
        {"SNAPSHOT": {"SnapshotCreationDate": "2015-06-21 17:33:41"}},
        {"CafeData": {"CafeVersion": "2807"}},
        {"CafeData": {"IsSoftwareOnly": "1"}},
        {"CafeData": {"IsPassportTCPIP": "1"}},
        {"SNAPSHOT": {"SnapshotVersion": "777"}},
        {"SNAPSHOT": {"SnapshotCreationDate": "2017-07-27 17:37:47"}},
    ]
    
    def main(*argv):
        res = []
        for k, g in it.groupby(l, key=lambda x: next(iter(x))):
            res_item = {}
            for item in g:
                res_item.update(item[k])
            res.append({k: res_item})
        pp(res)
    
    
    if __name__ == "__main__":
        print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        rc = main(*sys.argv[1:])
        print("\nDone.")
        sys.exit(rc)
    

    输出

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q067328076]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py
    Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 64bit on win32
    
    [{'SNAPSHOT': {'SnapshotCreationDate': '2015-06-21 17:33:41',
                   'SnapshotVersion': '304'}},
     {'CafeData': {'CafeVersion': '2807',
                   'IsPassportTCPIP': '1',
                   'IsSoftwareOnly': '1'}},
     {'SNAPSHOT': {'SnapshotCreationDate': '2017-07-27 17:37:47',
                   'SnapshotVersion': '777'}}]
    
    Done.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-02
      相关资源
      最近更新 更多