合并 Python 中相同键的字典
Merging dictionaries for same key in Python
这是我迄今为止尝试查看具有相同键的三个词典并添加其适当值的代码。如果不存在密钥,我希望代码添加一个零。
#!/usr/bin/env python
import sys
from operator import itemgetter
import csv
import ast
from collections import defaultdict
super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}
for d in (d1, d2, d3):
for key, value in d.iteritems():
super_dic.setdefault(key, []).append(value)
print super_dic
super_dic 构建的输出:
{'a': [2, 3], 'c': [3, 3], 'b': [5, 4], 'd': [6, 4]}
但是,我希望我的最终结果是:
{'a':[2, 3, 0], 'c':[3,3,0], 'b':[5,0,4],'d':[6,0,4]}
值的顺序很重要
任何 help/feedback 非常感谢。现在已经为此奋斗了一段时间,尝试过的所有方法最终都没有建立正确的主词典。
*请注意,这不是一个重复的问题,因为在 Python 中提出的合并词典的问题都忽略了添加 zero 的事实,如果关键项没有存在。 *
我找到了一个有点(笨拙)的解决方案:
from collections import defaultdict
super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}
# Counter because it might be that there is some element only present in a later dict.
# And we need to compare the current list lengths in each turn
i = 0
for d in (d1, d2, d3):
for key in d:
# It might be that a key wasn't present before so set default to [0]*i
super_dic.setdefault(key, [0]*i).append(d[key])
# Increment i so we can compare the list lengths:
i += 1
# Append 0 for every key that wasn't appended in this turn:
for key in super_dic:
if len(super_dic[key]) < i:
super_dic[key].append(0)
print(super_dic)
{'b': [5, 0, 4], 'a': [2, 3, 0], 'd': [6, 0, 4], 'c': [3, 3, 0]}
解释在代码注释中我希望它是可以理解的,否则我会进一步详细说明。有什么不明白的就评论吧。
更一般地说,假设您有一个名为 dicts
.
的词典列表
>>> dicts = [d1, d2, d3]
>>> allkeys = set(x for d in dicts for x in d.keys())
>>> super_dic = {k:[d.get(k, 0) for d in dicts] for k in allkeys}
>>> super_dic
{'a': [2, 3, 0], 'c': [3, 3, 0], 'b': [5, 0, 4], 'd': [6, 0, 4]}
我会这样做。获取集合中的所有键,创建一个带有列表功能的defaultdict
。然后遍历所有字典的所有键。
all_keys = set(d1).union(d2).union(d3)
merged_dict = defaultdict(list)
for d in (d1,d2,d3):
for key in all_keys:
merged_dict[key] += d.get(key, 0),
print merged_dict
这是我迄今为止尝试查看具有相同键的三个词典并添加其适当值的代码。如果不存在密钥,我希望代码添加一个零。
#!/usr/bin/env python
import sys
from operator import itemgetter
import csv
import ast
from collections import defaultdict
super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}
for d in (d1, d2, d3):
for key, value in d.iteritems():
super_dic.setdefault(key, []).append(value)
print super_dic
super_dic 构建的输出:
{'a': [2, 3], 'c': [3, 3], 'b': [5, 4], 'd': [6, 4]}
但是,我希望我的最终结果是:
{'a':[2, 3, 0], 'c':[3,3,0], 'b':[5,0,4],'d':[6,0,4]}
值的顺序很重要
任何 help/feedback 非常感谢。现在已经为此奋斗了一段时间,尝试过的所有方法最终都没有建立正确的主词典。
*请注意,这不是一个重复的问题,因为在 Python 中提出的合并词典的问题都忽略了添加 zero 的事实,如果关键项没有存在。 *
我找到了一个有点(笨拙)的解决方案:
from collections import defaultdict
super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}
# Counter because it might be that there is some element only present in a later dict.
# And we need to compare the current list lengths in each turn
i = 0
for d in (d1, d2, d3):
for key in d:
# It might be that a key wasn't present before so set default to [0]*i
super_dic.setdefault(key, [0]*i).append(d[key])
# Increment i so we can compare the list lengths:
i += 1
# Append 0 for every key that wasn't appended in this turn:
for key in super_dic:
if len(super_dic[key]) < i:
super_dic[key].append(0)
print(super_dic)
{'b': [5, 0, 4], 'a': [2, 3, 0], 'd': [6, 0, 4], 'c': [3, 3, 0]}
解释在代码注释中我希望它是可以理解的,否则我会进一步详细说明。有什么不明白的就评论吧。
更一般地说,假设您有一个名为 dicts
.
>>> dicts = [d1, d2, d3]
>>> allkeys = set(x for d in dicts for x in d.keys())
>>> super_dic = {k:[d.get(k, 0) for d in dicts] for k in allkeys}
>>> super_dic
{'a': [2, 3, 0], 'c': [3, 3, 0], 'b': [5, 0, 4], 'd': [6, 0, 4]}
我会这样做。获取集合中的所有键,创建一个带有列表功能的defaultdict
。然后遍历所有字典的所有键。
all_keys = set(d1).union(d2).union(d3)
merged_dict = defaultdict(list)
for d in (d1,d2,d3):
for key in all_keys:
merged_dict[key] += d.get(key, 0),
print merged_dict