给定n个列表,其中包含m个词典作为其元素,我想生成一个新列表,其中包含一组连接的词典。
l1 = [{"index":'a', "b":2,'c':9}, {"index":'b', "b":3,"c":5}, {"index":'c', "b":8,"c":8}]
l2 = [{"index":'a', "b":4,'c':8}, {"index":'b', "b":9,"c":10},{"index":None, "b":11,"c":10}]
我想制作一个联合名单:
l3 = [{"index":'a', "b":6, "c":17},
{"index":'b', "b":12, "c":15},
{"index":'c', "b":8, "c":8},
{"index":None, "b":11,"c":10}]
我有一个可以合并两个列表的方法。但正如您在上面所看到的,我也想添加这些元素。
def merge_lists(l1, l2, key):
merged = {}
for item in l1+l2:
if item[key] in merged:
merged[item[key]].update(item)
else:
merged[item[key]] = item
return [val for (_, val) in merged.items()]
l3 = merge_lists(l1,l2,'index')
在Python中执行此操作的最有效方法是什么?
答案 0 :(得分:4)
你可以很容易地使用Counter
这样的东西......
from collections import defaultdict, Counter
def merge_lists(l1, l2):
d = defaultdict(Counter)
for sdict in l1 + l2:
counter = Counter(sdict)
d[counter.pop('index')] += counter
lists = []
for k, v in d.items():
result = dict(v)
result['index'] = k
lists.append(result)
return lists
l1 = [{"index":'a', "b":2,'c':9}, {"index":'b', "b":3,"c":5}, {"index":'c', "b":8,"c":8}]
l2 = [{"index":'a', "b":4,'c':8}, {"index":'b', "b":9,"c":10},{"index":None, "b":11,"c":10}]
print(merge_lists(l1, l2))
添加Counter
实例的好处在于它几乎可以满足您的期望。如果一个计数器没有密钥,它就不会对总和添加任何内容,但如果两个计数器都有给定的密钥,那么它们的值将被添加并用作该密钥的结果值。
请注意,合并列表的顺序是任意的(基于defaultdict
的顺序)。如果您需要以某种方式保留订单,可以在事后sort
或创建默认的有序字典,该字典会根据index
中l1
的首次显示时间保留订单或l2
:
class DefaultOrderedDict(collections.OrderedDict):
def __init__(self, default_factory, *args, **kwargs):
self.default_factory = default_factory
super(DefaultOrderedDict, self).__init__(*args, **kwargs)
def __missing__(self, key):
self[key] = self.default_factory()
return self[key]
(在ActiveState和StackOverflow上有更多“完整”的默认有序字符,但是这个简单的 应该可以解决您手头的问题)