为了账号安全,请及时绑定邮箱和手机立即绑定

组合具有相同 id 的字典的更快方法

组合具有相同 id 的字典的更快方法

PHP
catspeake 2023-11-09 10:53:21
假设我有以下具有相同属性 id 的字典列表。我想知道根据 id 值组合它们哪种更快、更正确。 perperson = [  {'id':1, 'firstName':'test','lastName':'testlast'},  {'id':2, 'firstName':'test2','lastName':'testlast2'},  {'id':3, 'firstName':'test3','lastName':'last3'},]peremail = [  {'id':1, 'email':'test@test'},  {'id':2, 'email':'test2@test2'},  {'id':3, 'email':'test3@test3'},]结果 comdined= [  {'id':1, 'firstName':'test','lastName':'testlast','email':'test@test'},  {'id':2, 'firstName':'test2','lastName':'testlast2','email':'test2@test2'},  {'id':3, 'firstName':'test3','lastName':'last3','email':'test3@test3'},]
查看完整描述

4 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

将列表之一转换为字典,然后执行查找


前任:


perperson = [

  {'id':1, 'firstName':'test','lastName':'testlast'},

  {'id':2, 'firstName':'test2','lastName':'testlast2'},

  {'id':3, 'firstName':'test3','lastName':'last3'},

]


peremail = [

  {'id':1, 'email':'test@test'},

  {'id':2, 'email':'test2@test2'},

  {'id':3, 'email':'test3@test3'},

]

peremail_t = {i.pop('id'): i for i in peremail}    # Easy look-up


comdined = [{**i, **peremail_t[i['id']]} for i in perperson]

print(comdined)

输出:


[{'email': 'test@test', 'firstName': 'test', 'id': 1, 'lastName': 'testlast'},

 {'email': 'test2@test2',

  'firstName': 'test2',

  'id': 2,

  'lastName': 'testlast2'},

 {'email': 'test3@test3', 'firstName': 'test3', 'id': 3, 'lastName': 'last3'}]

或就地更新


前任:


for i in perperson:

    i.update(peremail_t[i['id']])


查看完整回答
反对 回复 2023-11-09
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

如果您正在处理字典列表中的大量类似表格的数据,请考虑使用 Pandas 数据框。按 id合并数据帧非常简单,如果表很大,速度会更快,并且它为您提供了更多方法来处理 id 不匹配等潜在问题。


import pandas as pd

merged = pd.DataFrame(perperson).merge(pd.DataFrame(peremail), on="id")

merged.to_dict("records")如果您需要将其转换回字典,则可以使用。


如果您不想使用 pandas,这里有一个生成器,可以合并任意数量的字典列表,这些字典列表可能未排序并且可能具有不匹配的 id(相当于 pandas 中的“外部”合并)。这可能比将列表转换为字典慢,但使用列表尽可能高效。


def join_by_key(key, *lists):

    lists = [sorted(L, key=lambda d: d[key]) for L in lists]

    while lists:

        min_key = min(L[0][key] for L in lists)

        r = {}

        for L in lists:

            if L[0][key] == min_key:

                r.update(L.pop(0))

        yield r

        lists = [L for L in lists if L]

            

print(list(join_by_key("id", perperson, peremail)))


查看完整回答
反对 回复 2023-11-09
?
慕标5832272

TA贡献1966条经验 获得超4个赞

考虑到所有字典都有一个“id”键,并且列表按“id”值排序:



def combine_dicts(dict_1, dict_2):

    if dict_1['id'] == dict_2['id']:

        for k in dict_2:

            if k in dict_1:

                continue

            else:

                dict_1.update({k:dict_2[k]})

    return dict_1



for dict1, dict2 in zip(perperson, peremail):

    combine_dicts(dict1, dict2)


查看完整回答
反对 回复 2023-11-09
?
慕容森

TA贡献1853条经验 获得超18个赞

这是我的建议,一个简单的循环:


perperson = [{'id':1, 'firstName':'test','lastName':'testlast'},

{'id':2, 'firstName':'test2','lastName':'testlast2'},

{'id':3, 'firstName':'test3','lastName':'last3'},

]


peremail = [

{'id':1, 'email':'test@test'},

{'id':2, 'email':'test2@test2'},

{'id':3, 'email':'test3@test3'},

]



for n,j in zip(perperson,peremail):

    n['email']=j['email']


print(perperson)

她是输出


[{'lastName': 'testlast', 'id': 1, 'firstName': 'test', 'email': 'test@test'},      {'lastName': 'testlast2', 'id': 2, 'firstName': 'test2', 'email': 'test2@test2'}, {'lastName': 'last3', 'id': 3, 'firstName': 'test3', 'email': 'test3@test3'}]



查看完整回答
反对 回复 2023-11-09
  • 4 回答
  • 0 关注
  • 120 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信