让我们假设我有两个字典:
dic1 = { "first":1, "second":4, "third":8}
dic2 = { "first":9, "second":5, "fourth":3}
是否有一种简单的方法来获取类似于以下内容的内容?
dic3 = { "first":[1,9], "second":[4,5], "third":[8], "fourth":[3]}
我使用列表来存储值,但是元组也可以。
答案 0 :(得分:6)
您可以使用defaultdict
来保存列表,然后将值附加到列表中。这种方法很容易扩展到任意数量的词典。
from collections import defaultdict
dd = defaultdict(list)
dics = [dic1, dic2]
for dic in dics:
for key, val in dic.iteritems(): # .items() in Python 3.
dd[key].append(val)
>>> dict(dd)
{'first': [1, 9], 'fourth': [3], 'second': [4, 5], 'third': [8]}
所有具有单个值的键仍保留在列表中,这可能是最好的方法。但是,您可以将长度为1的任何内容更改为实际值,例如
for key, val in dd.iteritems(): # .items() in Python 3.
if len(val) == 1
dd[key] = val[0]
答案 1 :(得分:6)
这是一个幼稚的解决方案;将其中一个字典复制到结果上,并迭代另一个字典的键和值,并根据需要向结果中添加数组。由于只有两个字典,因此没有合并数组具有超过2个项目;无需检查类型。
dic1 = {"first": 1, "second": 4, "third": 8}
dic2 = {"first": 9, "second": 5, "fourth": 3}
dic3 = dict(dic2)
for k, v in dic1.items():
dic3[k] = [dic3[k], v] if k in dic3 else v
print(dic3)
输出:
{'first': [9, 1], 'second': [5, 4], 'fourth': 3, 'third': 8}
如果您希望单个值成为列表,则可以使用:
dic3 = {k: [v] for k, v in dic2.items()}
for k, v in dic1.items():
dic3[k] = dic3[k] + [v] if k in dic3 else [v]
答案 2 :(得分:3)
使用集合和字典理解
L = [d1, d2]
dups = set(d1.keys() & d2.keys())
d = {k: [L[0][k], L[1][k]] if k in dups else i[k] for i in L for k in i}
{'first': [1, 9], 'second': [4, 5], 'third': 8, 'fourth': 3}
答案 3 :(得分:2)
通常,我会说将不同键的值转换为不同的对象类型是一种不好的做法。我只会做类似的事情:
def merge_values(val1, val2):
if val1 is None:
return [val2]
elif val2 is None:
return [val1]
else:
return [val1, val2]
dict3 = {
key: merge_values(dic1.get(key), dic2.get(key))
for key in set(dic1).union(dic2)
}
答案 4 :(得分:1)
给出:
dic1 = { "first":1, "second":4, "third":8}
dic2 = { "first":9, "second":5, "fourth":3}
您可以使用.setdefault
:
dic_new={}
for k,v in list(dic1.items())+list(dic2.items()):
dic_new.setdefault(k, []).append(v)
else:
dic_new={k:v if len(v)>1 else v[0] for k,v in dic_new.items()}
>>> dic_new
{'first': [1, 9], 'second': [4, 5], 'third': 8, 'fourth': 3}
这将产生相关的输出。我认为将单个元素列表展平为不同的对象类型是不必要的复杂性。
进行编辑后,将产生所需的结果:
dic_new={}
for k,v in list(dic1.items())+list(dic2.items()):
dic_new.setdefault(k, []).append(v)
>>> dic_new
{'first': [1, 9], 'second': [4, 5], 'third': [8], 'fourth': [3]}
答案 5 :(得分:1)
创建一个新字典dic
,其中的键为dic1
和dic2
,并为一个空列表赋值,然后遍历dic1
和dic2
追加值dic
:
dic1 = { "first":1, "second":4, "third":8}
dic2 = { "first":9, "second":5, "fourth":3}
dic = {key:[] for key in list(dic1.keys()) + list(dic2.keys())}
for key in dic1.keys():
dic[key].append(dic1[key])
for key in dic2.keys():
dic[key].append(dic2[key])
答案 6 :(得分:0)
from copy import deepcopy
def _add_value_to_list(value, lis):
if value:
if isinstance(value, list):
lis.extend(value)
else:
lis.append(value)
else:
pass
def _merge_value(value_a, value_b):
merged_value = []
_add_value_to_list(value_a, merged_value)
_add_value_to_list(value_b, merged_value)
return merged_value
def _recursion_merge_dict(new_dic, dic_a, dic_b):
if not dic_a or not dic_b:
return new_dic
else:
if isinstance(new_dic, dict):
for k, v in new_dic.items():
new_dic[k] = _recursion_merge_dict(v, dic_a.get(k, {}), dic_b.get(k, {}))
return new_dic
else:
return _merge_value(dic_a, dic_b)
def merge_dicts(dic_a, dic_b):
new_dic = deepcopy(dic_a)
new_dic.update(dic_b)
return _recursion_merge_dict(new_dic, dic_a, dic_b)
答案 7 :(得分:0)
列表字典的解决方案(改编自@dawg):
dic1 = { "first":[1], "second":[4], "third":[8]}
dic2 = { "first":[9], "second":[5], "fourth":[3]}
dic_new={}
for k,v in list(dic1.items())+list(dic2.items()):
dic_new.setdefault(k, []).extend(v)
>>> dic_new
{'first': [1, 9], 'second': [4, 5], 'third': [8], 'fourth': [3]}