合并dict数组中的重复条目

时间:2014-11-24 17:17:10

标签: python arrays recursion dictionary merge

我正在努力解决递归合并问题。

让我说我有:

a=[{'name':"bob", 
    'age':10, 
    'email':"bob@bla", 
    'profile':{'id':1, 'role':"admin"}}, 
   {'name':"bob", 
    'age':10, 
    'email':"other mail", 
    'profile':{'id':2, 'role':"dba"},
    'home':"/home/bob"
  }]

我需要一些东西来递归合并条目。如果同一级别上现有给定键的值不同,则将该值附加到数组。

b = merge(a)
print b
{'name':"bob", 
 'age':10, 
 'email':["bob@bla","other mail"], 
 'profile':{'id':[1,2], 'role'=["admin", "dba"], 'home':"/home/bob"}

我写了这段代码:

def merge(items):
    merged = {}
    for item in items:
        for key in item.keys():
            if key in merged.keys():
                if item[key] != merged[key]:
                    if not isinstance(merged[key], list):
                        merged[key] = [merged[key]]
                    if item[key] not in merged[key]:
                        merged[key].append(item[key])
            else:
                merged[key] = item[key]
    return merged 

输出结果为:

{'age': 10,
 'email': ['bob@bla', 'other mail'],
 'home': '/home/bob',
 'name': 'bob',
 'profile': [{'id': 1, 'role': 'admin'}, {'id': 2, 'role': 'dba'}]}

这不是我想要的。

我无法弄清楚如何处理递归。

谢谢:)

1 个答案:

答案 0 :(得分:0)

当您遍历参数中的每个字典,然后每个字典中的每个键和值时,您需要以下规则:

  1. 如果输出中没有任何内容反对该键,请将新键和值添加到输出中;
  2. 如果该键有值,并且与新值相同,则不执行任何操作;
  3. 如果该键有值,并且它是一个列表,append列表的新值;
  4. 如果该键存在值,并且它是字典,则使用现有字典递归merge新值;
  5. 如果该键有值,并且它既不是列表也不是字典,请在输出中输入当前值和新值的列表。
  6. 在代码中:

    def merge(*dicts):
        """Recursively merge the argument dictionaries."""
        out = {}
        for dct in dicts:
            for key, val in dct.items():
                try:
                    out[key].append(val) # 3.
                except AttributeError:
                    if out[key] == val:
                        pass # 2.
                    elif isinstance(out[key], dict):
                        out[key] = merge(out[key], val) # 4.
                    else:
                        out[key] = [out[key], val] # 5.
                except KeyError:
                    out[key] = val # 1.
        return out
    

    使用中:

    >>> import pprint
    >>> pprint.pprint(merge(*a))
    {'age': 10,
     'email': ['bob@bla', 'other mail'],
     'home': '/home/bob',
     'name': 'bob',
     'profile': {'id': [1, 2], 'role': ['admin', 'dba']}}