合并多个词典列表

时间:2019-09-23 17:15:47

标签: python dictionary

我有几个词典列表,其中每个词典都包含一个唯一的id值,该值在所有列表中都通用。我想将它们合并为一个字典列表,其中每个字典都以该id值进行连接。

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

desired_output = [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]

我尝试做类似在https://stackoverflow.com/a/42018660/7564393中找到的答案,但是由于我有两个以上的列表,我感到非常困惑。我应该尝试使用defaultdict方法吗?更重要的是,我不会总是知道其他值,而只是在所有字典中都存在id值。

6 个答案:

答案 0 :(得分:1)

您可以先构建一个字典,然后将其变成列表:

from itertools import chain
from collections import defaultdict

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

dict_out = defaultdict(dict)

for d in chain(list1, list2, list3):
    dict_out[d['id']].update(d)
out = list(dict_out.values())

print(out)
# [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]

itertools.chain允许您迭代3个列表中包含的所有字典。我们构建以id为键的字典dict_out,并将相应的字典构建为值。这样,我们可以使用当前迭代的小命令轻松update os.environ['PYTHONHASHSEED']

答案 1 :(得分:1)

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

# combine all lists
d = {} # id -> dict
for l in [list1, list2, list3]:
    for list_d in l:
        if 'id' not in list_d: continue
        id = list_d['id']
        if id not in d:
            d[id] = list_d
        else:
            d[id].update(list_d)

# dicts with same id are grouped together since id is used as key
res = [v for v in d.values()]
print(res)

答案 2 :(得分:1)

您可以使用itertools.groupby()

from itertools import groupby

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

desired_output = []
for _, values in groupby(sorted([*list1, *list2, *list3], key=lambda x: x['id']), key=lambda x: x['id']):
    temp = {}
    for d in values:
        temp.update(d)
    desired_output.append(temp)

结果:

[{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]

答案 3 :(得分:1)

在这里,我介绍了一种不使用 itertools 的功能方法(在快速开发工作中非常出色)。

该解决方案适用于任意数量的列表,因为该函数采用可变数量的参数,并且还允许用户指定返回输出的类型(列表/字典)。

默认情况下,它会根据需要返回列表,否则,如果您通过as_list = False,它将返回字典。

  

我更喜欢使用字典来解决此问题,因为它的快速性和搜索复杂度也更低。

只需看看下面的get_packed_list()函数。

get_packed_list()

def get_packed_list(*dicts_lists, as_list=True):
    output = {}

    for dicts_list in dicts_lists:
        for dictionary in dicts_list:
            _id = dictionary.pop("id") # id() is in-built function so preferred _id

            if _id not in output:
                # Create new id
                output[_id] = {"id": _id}

            for key in dictionary:
                output[_id][key] = dictionary[key]

            dictionary["id"] = _id # push back the 'id' after work (call by reference mechanism)

    if as_list:
        return [output[key] for key in output]

    return output # dictionary

Test

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]


output = get_packed_list(list1, list2, list3)
print(output) 
# [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]

output = get_packed_list(list1, list2, list3, as_list=False)
print(output)
# {1: {'id': 1, 'value': 20, 'sum': 10, 'total': 30}, 2: {'id': 2, 'value': 21, 'sum': 11, 'total': 32}}

答案 4 :(得分:0)

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

print(list1+list2+list3)

答案 5 :(得分:0)

list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]

result = []
for i in range(0,len(list1)):
      final_dict = dict(list(list1[i].items()) + list(list2[i].items()) + list(list3[i].items()))
      result.append(final_dict)

print(result)

输出:[{'id':1,'value':20,'sum':10,'total':30},{'id':2,'value':21,'sum':11 ,“总计”:32}]