我想在具有匹配的键:值对的字典列表中合并/合并多个字典。但是,我不希望这些对中的“值”本身成为每个新形成的词典中的列表。每个字典具有相同的键集,但是除了要组合的键之外,大多数key:value对将是唯一的。我知道我可以根据此示例中的匹配键来组合字典:
>>>from collections import defaultdict
d1 = {'A': 'str1', 'B': 41, 'C': 32}
d2 = {'A': 'str1', 'B': 12, 'C': 62}
d3 = {'A': 'str2', 'B': 47, 'C': 73}
d4 = {'A': 'str2', 'B': 101, 'C': 93}
dd = defaultdict(list)
for d in [d1, d2, d3, d4]: # you can list as many input dicts as you want here, I'll have a few thousand
for key, value in d.items():
dd[key].append(value)
print(dd)
这给了我预期的结果:
defaultdict(<class 'list'>, {'A': ['str1', 'str1', 'str2', 'str2'],
'B': [41, 12, 47, 101],
'C': [32, 62, 73, 93]})
当我 想要 达到我想要的结果时,实际上是这样的:
[{'A': 'str1', 'B': [41, 12], 'C': [32, 62]},
{'A': 'str2', 'B': [47, 101], 'C': [73, 93]}]
例如来自匹配键'B'
和'C'
的值构成列表,仅在键'A'
下存在匹配的key:value对时组合字典,而不会在{{1}中形成相同值的列表}
答案 0 :(得分:1)
您可以执行以下操作:
from collections import defaultdict
from functools import reduce
from itertools import chain
def merge(d1, d2, key='A'):
r = defaultdict(list)
for k, v in chain(d1.items(), d2.items()):
if k != key:
r[k].extend(v if isinstance(v, list) else [v])
return {**r, key: d1[key]}
d1 = {'A': 'str1', 'B': 41, 'C': 32}
d2 = {'A': 'str1', 'B': 12, 'C': 62}
d3 = {'A': 'str2', 'B': 47, 'C': 73}
d4 = {'A': 'str2', 'B': 101, 'C': 93}
common = defaultdict(list)
for d in [d1, d2, d3, d4]:
common[d['A']].append(d)
result = [reduce(merge, value) for value in common.values()]
print(result)
输出
[{'B': [41, 12], 'C': [32, 62], 'A': 'str1'}, {'B': [47, 101], 'C': [73, 93], 'A': 'str2'}]
答案 1 :(得分:1)
dd2=[]
for d in [d1,d2,d3,d4]:
found=False
for dtmp in dd2:
if dtmp['A'] == d['A']:
dtmp['B'].append(d['B'])
dtmp['C'].append(d['C'])
found=True
if not found:
dtmp2={'A':d['A'],'B':[d['B']],'C':[d['C']]}
dd2.append(dtmp2)
dd2将是您想要的。