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

时间:2020-10-15 13:39:36

标签: python

可以说,我有以下具有相同属性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 个答案:

答案 0 :(得分:1)

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

例如:

// in your activity, declare a list;
var mDocuments: List<DocumentSnapshot>? = null

// Then in getDataFromFirestore store that list
...
mDocuments = snapshot.documents;
val documents = snapshot.documents
for (document in documents) {
    ...
}
...

// And use it when calling itemDelete:
adapter = NoteAdapter(titleTextFromFB, imageFromFB, noteTextFromFB, object: NoteAdapter.onClick{
    override fun onItemClickListener(v: View, pos: Int, data: Any) {
        when(v.id){
            R.id.delete -> itemDelete(mDocuments[pos])
        }
    }
})

// To then finally delete the document by its ID
fun itemDelete(doc: DocumentSnapshot) {
    db.collection("Notes").document(doc.Id).delete()
}

输出:

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'}]

答案 1 :(得分:1)

如果在词典列表中处理大量类似表的数据,则可以考虑使用Pandas数据框。 Merging ID的数据帧非常简单,如果表很大,它将更快,并且它为您提供了更多方法来处理ID不匹配之类的潜在问题。

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

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

如果您不想使用熊猫,这是一个生成器,它可以合并任意数量的字典列表,这些字典可能没有排序,而且ID可能不匹配(等同于熊猫中的“外部”合并)。这可能比将列表转换成字典要慢,但是使用列表要尽可能地高效。

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)))

答案 2 :(得分:0)

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

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'}]

答案 3 :(得分:0)

考虑到所有词典都有一个“ 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)