2012-12-26 57 views
0

我正在嘗試使用字典爲我的抓取工具編制索引網頁,並且遇到了一些有趣的和內存問題。字典查詢時間

我創建一個字典索引(格式:關鍵字:[爲url1,url2 URL3,...]),我將用它來跟蹤哪些頁面包含哪些單詞。當我收集的網頁,我使用功能add_page_to_index()

def add_page_to_index(self, url): 
    for keyword in url.get_text().split(): 
     self.add_to_index(keyword, url) 
def add_to_index(self, keyword, url): 
    for word in self.index: 
     if word == keyword: 
      if url not in self.index[word]: 
       self.index[word].append(url) 
      return 
    # not found, add new keyword to index 
    self.index[keyword] = [url] 

此代碼一直擔任我的比較好(我知道它有性能問題,但效率不的本質爲這個項目),但是當我改變add_to_index()到這個:

def add_to_index(self, keyword, url): 
    if keyword in self.index: 
     self.index[keyword].append(url) 
    else: # not found, add new keyword to index 
     self.index[keyword] = [url] 

突然python的內存使用率skyrockets(我最終得到一個MemoryError)。這是我的代碼問題還是有其他解釋?

注意,我是一個高中生,所以我不一定有最廣泛的編程背景。

謝謝!

編輯:改爲我原來的。

+0

奇怪的存儲器也生長較快 - '指數= {} '在'索引'字之前'將保證沒有任何事情可以完成。您是否想將該行添加到add_to_index函數之外的某個位置作爲全局變量? – Amadan

+0

在這兩種情況下,'add_to_index'都會創建一個新字典,然後丟棄它。這個功能的重點是什麼? –

+0

'word'來自你的第二個代碼段? – miku

回答

0

罪魁禍首可能是在第二種情況下不存在的for word in self.indexif url not in self.index[keyword]和。沒有它:

  • 存儲器可以通過重複在self.index[keyword]
  • 代碼消耗得更快,從而,因爲更多的數據被處理
from collections import defaultdict 

def __init__(self, ...): 
    self.index = defaultdict(set) 
    # ... 

def add_page_to_index(self, page): 
    for keyword in page.get_text().split(): 
     self.add_to_index(keyword, page) 

def add_to_index(self, keyword, page): 
    self.index[keyword].add(page) 
0

您的兩套代碼之間的主要區別是以下行,其中僅出現在記憶體豬:

if keyword in self.index: 

我在這種情況下的猜測是,self.index是相當大的,而且不必檢查通過每次調用該方法時,都會造成什麼結果。

你也應該看看,如果你一定需要有所有你正在收集存儲在解釋記憶一次數據。您可能最好將盡可能多的數據存儲在某種更永久的結構中,例如csv或redis或類似的東西。

+0

'self.index'是一個字典,所以'self.index'中的關鍵字是O(1)攤銷。 – jfs