2

我有这个:

dict1 = defaultdict(lambda:defaultdict(list))
dict1['rl1']['sh1'] = ['a','b']
dict1['rl1']['sh2'] = ['c','d']
dict1['rl2']['sh1'] = ['c','d']

dict2 = defaultdict(lambda:defaultdict(list))
dict2['rl1']['sh1'] = ['p','q']
dict2['rl1']['sh3'] = ['r','s']
dict2['rl3']['sh1'] = ['r','s']

我想做两个默认字典的联合,这将是结果:

uniondict = defaultdict(lambda:defaultdict(list))
uniondict['rl1']['sh1'] = ['a','b','p','q']
uniondict['rl1']['sh2'] = ['c','d']
uniondict['rl1']['sh3'] = ['r','s']
uniondict['rl2']['sh1'] = ['c','d']
uniondict['rl3']['sh1'] = ['r','s']

我不确定如何获得此结果。我尝试使用 dict1.items() 和 dict2.items() 或更新函数,但我必须遗漏一些东西,因为我无法获得“联合” "的默认字典。

4

2 回答 2

7

稍微“优雅”一点:

uniondict = defaultdict(lambda:defaultdict(list))
for k1, v1 in dict1.items() + dict2.items():
    for k2, v2 in v1.items():
        uniondict[k1][k2] += v2

对于内存效率更高的解决方案:

from itertools import chain
uniondict = defaultdict(lambda:defaultdict(list))
for k1, v1 in chain(dict1.iteritems(), dict2.iteritems()):
    for k2, v2 in v1.iteritems():
        uniondict[k1][k2] += v2

这将使用迭代器来防止在内存中创建临时列表

itertools.chain 文档


对于后代,这是一个通用函数,它将合并第二层值支持+运算符的嵌套字典对象(defaultdict 或 no)。(列表、整数、集合等):

from collections import defaultdict
from itertools import chain

def merge_nested_dicts(dict_list):
    uniondict = defaultdict(lambda:defaultdict(list))
    for k1, v1 in chain(*[d.iteritems() for d in dict_list]):
        for k2, v2 in v1.iteritems():
            uniondict[k1][k2] += v2
    return uniondict
于 2012-05-30T17:50:20.963 回答
4
dict12 = defaultdict(lambda:defaultdict(list))
for k,v in dict1.items():
    for k1,v1 in v.items():
        dict12[k][k1] = v1
for k,v in dict2.items():
    for k2,v2 in v.items():
        dict12[k][k2] += v2
for k,v in dict12.items():
    for k12,v12 in v.items():
        print "dict12[%r][%r] = %r" % (k,k12,v12)
于 2012-05-30T17:18:39.317 回答