python:如何合并两个具有相同键名的字典

本问题已经有最佳答案,请猛点这里访问。

我是Python新手,正在尝试编写一个函数,将合并两个字典对象在Python。例如

1
2
dict1 = {'a':[1], 'b':[2]}
dict2 = {'b':[3], 'c':[4]}

我需要生成一个新的合并字典

1
dict3 = {'a':[1], 'b':[2,3], 'c':[4]}

函数还应该接受参数"conflict"(设置为True或False)。当冲突设置为False时,上面的设置没有问题。当冲突设置为True时,代码将像这样合并字典:

1
dict3 = {'a':[1], 'b_1':[2], 'b_2':[3], 'c':[4]}

我想把这两本词典加起来,但不知道怎么做才对。

1
2
3
for key in dict1.keys():
    if dict2.has_key(key):
        dict2[key].append(dict1[key])


如果你想要一个合并的副本,不改变原来的dicts和手表的名称冲突,你可能想试试这个解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#! /usr/bin/env python3
import copy
import itertools


def main():
    dict_a = dict(a=[1], b=[2])
    dict_b = dict(b=[3], c=[4])
    complete_merge = merge_dicts(dict_a, dict_b, True)
    print(complete_merge)
    resolved_merge = merge_dicts(dict_a, dict_b, False)
    print(resolved_merge)


def merge_dicts(a, b, complete):
    new_dict = copy.deepcopy(a)
    if complete:
        for key, value in b.items():
            new_dict.setdefault(key, []).extend(value)
    else:
        for key, value in b.items():
            if key in new_dict:
                # rename first key
                counter = itertools.count(1)
                while True:
                    new_key = f'{key}_{next(counter)}'
                    if new_key not in new_dict:
                        new_dict[new_key] = new_dict.pop(key)
                        break
                # create second key
                while True:
                    new_key = f'{key}_{next(counter)}'
                    if new_key not in new_dict:
                        new_dict[new_key] = value
                        break
            else:
                new_dict[key] = value
    return new_dict


if __name__ == '__main__':
    main()

程序显示了两个合并字典的如下表示:

1
2
{'a': [1], 'b': [2, 3], 'c': [4]}
{'a': [1], 'b_1': [2], 'b_2': [3], 'c': [4]}

我想你想这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dict1 = {'a':[1], 'b':[2]}
dict2 = {'b':[3], 'c':[4]}

def mergeArray(conflict):
    for key in dict1.keys():
        if dict2.has_key(key):
            if conflict==False:
                dict2[key].extend(dict1[key])
            else:
                dict2[key+'_1'] = dict1[key]
                dict2[key+'_2'] = dict2.pop(key)
        else:
            dict2[key] = dict1[key]

mergeArray(True);
print dict2