首页 > 解决方案 > 如何根据 Python 中的公共键值对有效地将键值从一个字典列表插入到另一个字典列表中?

问题描述

我在 python 中有这么大的字典列表。下面是一个例子:

big_list_dictionary = [{
    'name': 'test = 1',
    'id': 1,
    'value': 30
},{
    'name': 'apple = 1',
    'id': 2,
    'value': 70
},{
    'name': 'orange = 1',
    'id': 3,
    'value': 10
},{
    'name': 'balloon = 1',
    'id': 4,
    'value': 20
},{
    'name': 'airplane = 1',
    'id': 5,
    'value': 40
}]

我有两个字典的列表及其总值

total1 = [{
    'name': 'test',
    'total': 130
},{
    'name': 'apple',
    'total': 270
},{
    'name': 'orange',
    'total': 310
},{
    'name': 'balloon',
    'total': 420
},{
    'name': 'airplane',
    'total': 540
}]

total2 = [{
    'name': 'test',
    'total': 230
},{
    'name': 'apple',
    'total': 570
},{
    'name': 'orange',
    'total': 3210
},{
    'name': 'balloon',
    'total': 620
},{
    'name': 'airplane',
    'total': 940
}]

如果您注意到,namein total1and与where被省略的地方total2稍有不同。big_list_dictionary= 1

如何添加从total1total2到的总值,big_list_dictionary以便最终结果如下所示:

[{
    'name': 'test = 1',
    'id': 1,
    'value': 30,
    'total2': 230,
    'total1': 130
},{
    'name': 'apple = 1',
    'id': 2,
    'value': 70,
    'total2': 570,
    'total1': 270
},{
    'name': 'orange = 1',
    'id': 3,
    'value': 10,
    'total2': 3210,
    'total1': 310
},{
    'name': 'balloon = 1',
    'id': 4,
    'value': 20,
    'total2': 620,
    'total1': 420
},{
    'name': 'airplane = 1',
    'id': 5,
    'value': 40,
    'total2': 940,
    'total1': 540
}]

目前,我这样做的方式非常缓慢。

    for item in big_list_dictionary:
        for t1,t2 in zip(total1,total2):
            if t1['name'] in item['name']:
                item['total1] = t1['total']
                item['total2'] = t2['total']

我怎样才能有效地做到这一点?

标签: pythonlistdictionaryoptimization

解决方案


如果额外的字符总是=1那么你可以创建一个中间关系,然后使用下面的代码。

big_list_dictionary = [{'name': 'test = 1','id': 1,'value': 30},{'name': 'apple = 1','id': 2,'value': 70},{'name': 'orange = 1','id': 3,'value': 10},{'name': 'balloon = 1','id': 4,'value': 20},{'name': 'airplane = 1','id': 5,'value': 40}]

total1 = [{ 'name': 'test','total': 130},{'name': 'apple','total': 270},
{'name': 'orange','total': 310},{'name': 'balloon','total': 420},{'name': 'airplane','total': 540}]
total2 = [{'name': 'test','total': 230},{'name': 'apple','total': 570},{'name': 'orange','total': 3210},{'name': 'balloon','total': 620},{'name': 'airplane','total': 940}]


intermediate = {i['name'].split('=')[0].strip():i for i in big_list_dictionary}

for t1, t2 in zip(total1, total2):
    intermediate[t1['name']]['total1'] = t1['total']
    intermediate[t1['name']]['total2'] = t2['total']

print(big_list_dictionary)

输出

[{'name': 'test = 1', 'id': 1, 'value': 30, 'total1': 130, 'total2': 230},
 {'name': 'apple = 1', 'id': 2, 'value': 70, 'total1': 270, 'total2': 570},
 {'name': 'orange = 1', 'id': 3, 'value': 10, 'total1': 310, 'total2': 3210},
 {'name': 'balloon = 1', 'id': 4, 'value': 20, 'total1': 420, 'total2': 620},
 {'name': 'airplane = 1', 'id': 5, 'value': 40, 'total1': 540, 'total2': 940}]

基准

%%timeit -n10 -r10,big_list_dictionarytotal1total2长度1000。长度已增加以显示效率。

此解决方案

513 µs ± 17.2 µs per loop (mean ± std. dev. of 10 runs, 10 loops each)

您的解决方案

91.6 ms ± 1.19 ms per loop (mean ± std. dev. of 10 runs, 10 loops each)

这个解决方案更快。( 513 µs < 91.6 ms)两种解之间的差异只会随着长度的增加而增加。

根据评论编辑:

我相信有一些元素 intest1test2不是 in big_list_dictionary,因为假设test1并且test2具有相同的元素以相同的顺序,您可以遍历列表之一,如果找不到,则追加并将其big_list_dictionary添加到intermediate. 这会将所有新字典附加到 的末尾big_list_dictionary,在末尾添加比在随机位置插入要快。但是,如果您确实关心订单,那么我相信您的解决方案将尽善尽美。

免责声明:我没有测试这部分代码,因为我没有输入或输出来检查所需的行为。

big_list_dictionary = [{'name': 'test = 1','id': 1,'value': 30},{'name': 'apple = 1','id': 2,'value': 70},{'name': 'orange = 1','id': 3,'value': 10},{'name': 'balloon = 1','id': 4,'value': 20},{'name': 'airplane = 1','id': 5,'value': 40}]
total1 = [{ 'name': 'test','total': 130},{'name': 'apple','total': 270},{'name': 'orange','total': 310},{'name': 'balloon','total': 420},{'name': 'airplane','total': 540}]
total2 = [{'name': 'test','total': 230},{'name': 'apple','total': 570},{'name': 'orange','total': 3210},{'name': 'balloon','total': 620},{'name': 'airplane','total': 940}]


intermediate = {i['name'].split('=')[0].strip():i for i in big_list_dictionary}


for t1 in total1:
    if t1['name'] not in intermediate:         
        temp_dict = {'name': t1['name'],'id': 0,'value': 0}
        big_list_dictionary.append(temp_dict)
        intermediate[t1['name']] = temp_dict


# insert rest of the answer from code above

推荐阅读