簡體   English   中英

python基於密鑰匹配合並字典的最快方法

[英]python quickest way to merge dictionaries based on key match

我有2個詞典列表。 列表A長34,000,列表B長650,000。 我基本上是根據鍵匹配將所有List B dicts插入到List A dicts中。 目前,我做的很明顯,但它永遠服用(嚴肅地說,就像一天)。 必須有一個更快的方式!

for a in listA:
    a['things'] = []
    for b in listB:
        if a['ID'] == b['ID']:
            a['things'].append(b)
from collections import defaultdict
dictB = defaultdict(list)
for b in listB:
    dictB[b['ID']].append(b)

for a in listA:
    a['things'] = []
    for b in dictB[a['ID']]:
        a['things'].append(b)

這會將你的算法從O(n * m)變為O(m)+ O(n),其中n = len(listA),m = len(listB)

基本上它通過'預先計算'從listB匹配每個'ID'的dicts來避免循環遍歷listB中每個dict的listB中的每個dict

這是一種可能有所幫助的方法。 我會留給你填寫細節。

你的代碼很慢,因為它是一個O(n ^ 2)算法,將每個A與每個B進行比較。

如果您首先按id(這些是O(nlogn))操作對listA和listB中的每一個進行排序,那么您可以輕松地遍歷A和B的排序版本(這將是線性時間)。

當您必須在非常大的數據集上進行外部合並時,這種方法很常見。 Mihai的答案更適合內部合並,你只需按id(在內存中)索引所有內容。 如果你有內存來保存這些額外的結構,並且字典查找是恆定的時間,那么這種方法可能會更快,更不用說更簡單了。 :)

舉個例子,假設A 在排序后有以下ID

acfgjp

排序后,B又有了這些ID

aaaabbbbcccddeeeefffggiikknnnnppppqqqrrr

奇怪的是,這個想法是將索引保持在A和B中(我知道這聽起來不像Pythonic)。 起初,你正在尋找a A和a在B.所以,你到B將所有的一對你的“東西”陣列走a 一旦你在B中消耗了a,你就會在A中向上移動一個到c 但是B中的下一個項目是b ,它小於c ,所以你必須跳過b。 然后你到達B中的c ,所以你可以開始為c添加“東西”。 以這種方式繼續,直到兩個列表都用盡。 只需一次通過。 :)

我將ListA和ListB轉換為字典,而不是以ID為鍵的字典。 然后使用python的快速字典查找附加數據是一件簡單的事情:

from collections import defaultdict

class thingdict(dict):
    def __init__(self, *args, **kwargs):
        things = []
        super(thingdict,self).__init__(*args, things=things, **kwargs)

A = defaultdict(thingdict)
A[1] = defaultdict(list)
A[2] = defaultdict(list, things=[6])  # with some dummy data
A[3] = defaultdict(list, things=[7])

B = {1: 5, 2: 6, 3: 7, 4: 8, 5: 9}

for k, v in B.items():
    # print k,v
    A[k]['things'].append(v)

print A
print B

返回:

defaultdict(<class '__main__.thingdict'>, {
    1: defaultdict(<type 'list'>, {'things': [5]}),
    2: defaultdict(<type 'list'>, {'things': [6, 6]}),
    3: defaultdict(<type 'list'>, {'things': [7, 7]}),
    4: {'things': [8]},
    5: {'things': [9]}
})
{1: 5, 2: 6, 3: 7, 4: 8, 5: 9}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM