如何在 python 中添加 AN OrderedDict()
How to add N OrderDict() in python
假设我有2个OrderedDict(),我可以通过以下操作得到(+)操作的结果:
dict1 = OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 0),
(3, 0),
(4, 0),
(5, 0),
(6, 0),
(7, 0),
(8, 0),
(9, 0),
(10, 0),
(11, 1)])
dict2 = OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 5),
(3, 0),
(4, 0),
(5, 0),
(6, 1),
(7, 0),
(8, 0),
(9, 0),
(10, 1),
(11, 1)])
dict3 = OrderedDict((k, dict1[k] + dict2[k]) for k in dict1 if k in dict2)
print(dict3)
OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 5),
(3, 0),
(4, 0),
(5, 0),
(6, 1),
(7, 0),
(8, 0),
(9, 0),
(10, 1),
(11, 2)])
我的问题是:如何概括上述操作,以便获得 N OrderedDict() 的 (+) 运算结果?
使用 map-reduce 的一些天真的方法。请注意,我没有测试以下代码,因此可能需要进行一些调整
import operator
dicts = [dict1, dict2, dict3, dict4]
dicts_keys = map(lambda d: set(d.keys()), dicts)
common_keys = set.intersection(*dicts_keys)
sum_dict = OrderedDict(
(k, reduce(operator.add, map(lambda d: d[k], dicts)))
for k in common_keys)
通过测试每个键是否属于彼此的字典,您实际上是在执行集合交集的操作,但实际上您不能使用集合交集,因为集合在 Python.[=15 中是无序的=]
您可以通过安装 ordered-set 包来绕过这个限制,这样您就可以使用 OrderedSet.intersection
方法来获取按第一个字典中的键排序的字典中的公共键,您然后可以迭代构建一个新的 OrderedDict
,每个值都是所有字典中当前键的值的总和:
from ordered_set import OrderedSet
dicts = [dict1, dict2]
common_keys = OrderedSet.intersection(*dicts)
print(OrderedDict((k, sum(d[k] for d in dicts)) for k in common_keys))
如果您不想安装外部包,可以使用此功能实现类似的结果:
def add_dicts(*args):
items_list = list()
for k in args[0]:
if all([k in arg for arg in args[1:]]):
value = 0
for arg in args:
value += arg[k]
items_list.append((k, value))
return OrderedDict(items_list)
调用它:
dict3 = add_dicts(dict1, dict2)
dict4 = add_dicts(dict1, dict2, dict3)
如果你想用字典列表调用它:
dict_list=[dict1, dict2]
dict5 = add_dicts(*dict_list)
有关 *args 的更多信息可以在此 answer
中找到
假设我有2个OrderedDict(),我可以通过以下操作得到(+)操作的结果:
dict1 = OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 0),
(3, 0),
(4, 0),
(5, 0),
(6, 0),
(7, 0),
(8, 0),
(9, 0),
(10, 0),
(11, 1)])
dict2 = OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 5),
(3, 0),
(4, 0),
(5, 0),
(6, 1),
(7, 0),
(8, 0),
(9, 0),
(10, 1),
(11, 1)])
dict3 = OrderedDict((k, dict1[k] + dict2[k]) for k in dict1 if k in dict2)
print(dict3)
OrderedDict([(52, 0),
(53, 0),
(1, 0),
(2, 5),
(3, 0),
(4, 0),
(5, 0),
(6, 1),
(7, 0),
(8, 0),
(9, 0),
(10, 1),
(11, 2)])
我的问题是:如何概括上述操作,以便获得 N OrderedDict() 的 (+) 运算结果?
使用 map-reduce 的一些天真的方法。请注意,我没有测试以下代码,因此可能需要进行一些调整
import operator
dicts = [dict1, dict2, dict3, dict4]
dicts_keys = map(lambda d: set(d.keys()), dicts)
common_keys = set.intersection(*dicts_keys)
sum_dict = OrderedDict(
(k, reduce(operator.add, map(lambda d: d[k], dicts)))
for k in common_keys)
通过测试每个键是否属于彼此的字典,您实际上是在执行集合交集的操作,但实际上您不能使用集合交集,因为集合在 Python.[=15 中是无序的=]
您可以通过安装 ordered-set 包来绕过这个限制,这样您就可以使用 OrderedSet.intersection
方法来获取按第一个字典中的键排序的字典中的公共键,您然后可以迭代构建一个新的 OrderedDict
,每个值都是所有字典中当前键的值的总和:
from ordered_set import OrderedSet
dicts = [dict1, dict2]
common_keys = OrderedSet.intersection(*dicts)
print(OrderedDict((k, sum(d[k] for d in dicts)) for k in common_keys))
如果您不想安装外部包,可以使用此功能实现类似的结果:
def add_dicts(*args):
items_list = list()
for k in args[0]:
if all([k in arg for arg in args[1:]]):
value = 0
for arg in args:
value += arg[k]
items_list.append((k, value))
return OrderedDict(items_list)
调用它:
dict3 = add_dicts(dict1, dict2)
dict4 = add_dicts(dict1, dict2, dict3)
如果你想用字典列表调用它:
dict_list=[dict1, dict2]
dict5 = add_dicts(*dict_list)
有关 *args 的更多信息可以在此 answer
中找到