在Python中递归地合并字典
我有两个函数,它们可以接收两个字典,并递归地将它们的值相加。
def recursive_dict_sum_helper(v1, d2, k):
try: v2 = d2[k]
except KeyError: return v1 #problem is here if key not found it just return value but what about rest of the keys which is in d2??
if not v1: return v2
# "add" two values: if they can be added with '+', then do so,
# otherwise expect dictionaries and treat them appropriately.
try:
if type(v1) == list and type(v2) == list:
v1.extend(v2)
return list(set(v1))
else:
return v1 + v2
except: return recursive_dict_sum(v1, v2)
def recursive_dict_sum(d1, d2):
if len(d1) < len(d2):
temp = d1
d1 = d2
d2 = temp
# Recursively produce the new key-value pair for each
# original key-value pair, and make a dict with the results.
return dict(
(k, recursive_dict_sum_helper(v, d2, k))
for (k, v) in d1.items()
)
如果我输入以下内容,输出结果是我预期的:
a = {'abc': {'missing': 1, 'modified': 0, 'additional': 2}}
b = {'abc': {'missing': 1, 'modified': 1, 'additional': 2}}
mn = recursive_dict_sum(a, b)
output: mn = {'abc': {'missing': 2, 'modified': 1, 'additional': 4}}
但是如果输入是:
a = {'abc': {'missing': 1, 'modified': 0, 'additional': 2}}
b = {'cde': {'missing': 1, 'modified': 1, 'additional': 2}}
output: {'abc': {'missing': 1, 'modified': 0, 'additional': 2}} #which is wrong
如果在第二个字典中找不到某个键,它就会返回第一个字典中的键值。那么这就只处理了第一个字典的内容,第二个字典里的其他键怎么办呢?我该如何更新上面的脚本,以便输出结果是:
output: {'abc': {'missing': 1, 'modified': 0, 'additional': 2}, 'cde': {'missing': 1, 'modified': 1, 'additional': 2}}
2 个回答
3
做成了一个超级生成器,听起来你喜欢这个样子 :)
def recursive_dict_sum(d1, d2):
return dict((k, ((d1[k] if k in d1 else d2[k])
if k not in d1 or k not in d2
else (d1[k] + d2[k] if not isinstance(d1[k], dict)
else recursive_dict_sum(d1[k], d2[k]))))
for k in set(d1.keys() + d2.keys()))
3
如果我理解你想做的事情没错,下面的代码就能实现你的需求:
def dict_sum(d1, d2):
if d1 is None: return d2
if d2 is None: return d1
if isinstance(d1, list) and isinstance(d2, list):
return list(set(d1 + d2))
try:
return d1 + d2
except TypeError:
# assume d1 and d2 are dictionaries
keys = set(d1.iterkeys()) | set(d2.iterkeys())
return dict((key, dict_sum(d1.get(key), d2.get(key))) for key in keys)
dict_sum(a, b)
会给出你想要的结果。
不过要注意,如果用不兼容的类型来调用它,比如:
dict_sum({'a': 1}, 2)
补充说明:要特别处理列表(创建一个只包含唯一元素的列表)。