2017-07-16 111 views
2

快速查找字典我有形式的大辭典(1mil的鍵):蟒蛇:從磁盤

{ 
    key1: { 
     file1: [number_list1], 
     file7: [number_list2], 
     file10: [number_list3], 
     ... 
    } 
    key2: { 
     file1: [number_list4], 
     file5: [number_list5], 
     file2: [number_list6], 
     ...    
    } 
    ... 
    ... 
} 

由於種種約束,構建它後,我無法保持它在內存中,有將其以醃漬形式轉儲到磁盤上。但是,我仍然希望從磁盤快速查找任何一個密鑰。 我的想法是把大字典分成更小的塊(0.5-1MB的球場)。這需要額外的鍵:塊映射,但允許我在查找過程中只加載必要的塊。我想出了以下算法:

def split_to_pages(self, big_dict): 
    page_buffer = defaultdict(lambda: defaultdict(list)) 
    page_size = 0 
    page_number = 0 
    symbol2page = {} 
    for symbol, files in big_dict.items(): 
     page_buffer[symbol] = files 
     symbol2page[symbol] = page_number 
     page_size += deep_sizeof_bytes(files) 
     if page_size > max_page_size: 
      save_page_to_file(page_number, page_buffer) 
      page_buffer.clear() 
      page_size = 0 
      page_number += 1 
    if page_size > 0: 
     save_page_to_file(page_number, page_buffer) 

此解決方案執行良好的靜態字典。然而,由於它代表了一個動態的實體,因此很有可能在操作過程中將新密鑰引入或從字典中刪除。爲了反映這種變化,我的解決方案需要從頭開始劃分整個字典。有沒有更好的方法來處理這種情況?我有一種感覺,這是一個我不知道的常見問題,已經提出了更好的解決方案。

編輯:

我試過shelve,約0.5秒鍵查找時間爲一個小型的數據庫(2K鍵),速度很慢。我上面介紹的半分頁調度算法大約是0.01s。 sqlite3做了1mil密鑰表的0.4s查找時間,我懷疑mongo會更快。我的用例開銷太多了。我想我會繼續我自己的分區數據庫實現。

+2

我猜這是數據庫被髮明的原因? – Grimmy

+0

同意。您可以嘗試使用'redis','mongoDB'或其他一些NoSQL存儲。 – bpscott

+0

你可以給'tinydb'一個鏡頭。不知道它可以處理多少數據。 – Grimmy

回答

0

這是一個常見問題。我想你應該看看數據庫像mongodb