我有两个大型嵌套字典,我需要合并为一个:
dict1={
1: {"trait1: 32", "trait2": 43, "trait 3": 98},
2: {"trait1: 38", "trait2": 40, "trait 3": 95},
....
}
和
dict2={
1: {"trait1: 32", "trait2": 43, "trait 4": 54},
2: {"trait1: 38", "trait2": 40, "trait 4": 56},
....
}
而我想得到的是:
dict3={
1: {"trait1: 32", "trait2": 43, "trait 3": 98, "trait 4": 54},
2: {"trait1: 38", "trait2": 40, "trait 3": 95, "trait 4": 56},
....
}
我尝试过使用:
dict3=dict(list(dict1.items()) + list(dict2.items()))
但它只是为我复制dict2。
我也试过像这样循环“主”键(我复制了第一个字典成为最终输出):
dict3 = dict(dict1)
for key1 in dict3:
for key2 in dict2:
dict3[key1].update({"trait4": dict2[key2]["trait4"]})
但这不起作用,只有每一个条目在输出中按预期出现。而且我很确定我的做法是错误的。任何帮助表示赞赏!
要实现您的目标,您所要做的就是检查字典是否包含密钥。你应该定义一个函数,例如update_keys()
,它将采用两个参数:dict1
和dict2
。
要检查dictionary
是否有key
只需写(如this question中所述):
if key in dictionary:
# Action you want to take if dictionary has key.
因此,您的解决方案将如下所示(请注意,deepcopy函数是从复制模块导入的,如下面的Update 1中所述):
#!/usr/bin/env python3
from copy import deepcopy
def update_keys(dict1, dict2):
result_dict = deepcopy(dict1)
for key in dict2:
if key in result_dict:
for sub_key in dict2[key]:
result_dict[key].update({sub_key: dict2[key][sub_key]})
else:
result_dict.update({key: dict2[key]})
return result_dict
dict3 = update_keys(dict1, dict2)
为了澄清事情,您可以使用dictionary.items()
中提到的this question来迭代使用值,因为在嵌套循环和多个if语句中,您可能会在所有变量之间丢失。
#!/usr/bin/env python3
from copy import deepcopy
dict1={
1: {"trait1": 32, "trait2": 43, "trait3": 98},
2: {"trait1": 38, "trait2": 40, "trait3": 95}
}
dict2={
1: {"trait1": 32, "trait2": 43, "trait4": 54},
2: {"trait1": 38, "trait2": 40, "trait4": 56}
}
def update_keys(dict_one, dict_two):
result_dict = deepcopy(dict_one)
for key, value in dict_two.items():
if key in result_dict:
for sub_key, sub_value in value.items():
if sub_key not in result_dict[key]:
result_dict[key].update({sub_key: sub_value})
else:
result_dict.update({key: value})
return result_dict
dict3 = update_keys(dict1, dict2)
更新1:感谢@shash678我可以改进我的答案。早先将字典传递给方法并通过分配新值创建浅拷贝来制作副本,如本question topic中所述。因此,如果要保留dict1,则必须导入copy
模块并使用deepcopy()
函数。感谢@shash678,这个答案在不修改dict1的情况下完成了它的工作。
如果两个dicts中的键可以假设相同(对于python 3.5+),我想提出一个非常方便的合并。如果密钥都相同,我们可以简单地这样做:
merged_dict = {}
for key in dict1.keys():
merged_dict[key] = {**dict1[key], **dict2[key]}
# result:
# merged_dict is {1: {'trait1': 32, 'trait2': 43, 'trait3': 98, 'trait4': 54},
# 2: {'trait1': 38, 'trait2': 40, 'trait3': 95, 'trait4': 56}}
在dict前面的双星解包它,从Python 3.5开始,这种语法将允许我们解析dict文字中的dicts,有效地合并它们。我在这里假设在原始字典的每个值中都是字典本身。您可以直接以某种方式解压缩嵌套dicts(而不是使用for循环),但我不知道如何(如果有人,请评论!)。
如果我们假设键可能不同,我们必须添加一些东西,但是没有嵌套结构,所以我认为它仍然很简单。例如,假设dict2具有键/值对{3:{'trait5':435,'trait7':42}}。
# find the shared keys, i.e. the intersection of the key sets
shared_keys = set(dict1.keys()).intersection(set(dict2.keys()))
merged_dict = {}
for key in shared_keys:
merged_dict[key] = {**dict1[key], **dict2[key]}
# now add any key/value pairs only in dict1
for key in set(dict1.keys()) - shared_keys:
merged_dict[key] = {**dict1[key]}
# and the same for dict2
for key in set(dict2.keys()) - shared_keys:
merged_dict[key] = {**dict2[key]}
# result:
# merged_dict is {1: {'trait1': 32, 'trait2': 43, 'trait3': 98, 'trait4': 54},
# 2: {'trait1': 38, 'trait2': 40, 'trait3': 95, 'trait4': 56}},
# 3: {'trait5': 435, 'trait7': 42}}
我使用set操作来获取共享密钥,然后仅在dict1和dict2中获取密钥。例如,{1,2,3}和{1,2}的交集是{1,2},而集合差异{1,2,3} - {1,2} = {3}。
我希望它足够清楚!
def merge_dict(x,y):
keys = list(set(x.keys() + y.keys()))
result = {}
for key in keys:
if key in x.keys():
z = x[key].copy()
if key in y.keys():
z.update(y[key])
result[key] = z
else:
result[key] = y[key]
result[k] = z
return result
dict3 = merge_dict(dict1,dict2)