[英]Writing b-tree in file using python
有一些文檔需要索引,這意味着我需要閱讀文檔並提取單詞並通過存儲它們出現在哪個文檔以及在哪個位置進行索引。
最初,我為每個單詞創建一個單獨的文件。 考慮2個文檔:
文件1
The Problem of Programming Communication with
文件2
Programming of Arithmetic Operations
因此將有10個單詞,其中8個是唯一的。 因此,我創建了8個文件。
用算術運算對通訊進行編程的問題
在每個文件中,我將存儲它們出現在哪個文檔中以及什么位置。 我正在實現的實際結構具有更多信息,但是此基本結構將達到目的。
文件名文件內容
1 1
問題1 2
的1 3 2 2
編程1 4 2 1
通訊1 5
與1 6
算術2 3
操作2 4
含義。 該單詞位於第一文檔的第三位置和第二文檔的第二位置。
初始索引完成后,我將所有文件連接到一個索引文件中,並在另一個文件中存儲將在其中找到特定單詞的偏移量。
索引文件:
1 1 1 2 1 3 2 2 1 4 2 1 1 5 1 6 2 3 2 4
偏移文件:
the 1 problem 3 of 5 programming 9 communications 13 with 15 arithmetic 17 operations 19
因此,如果我需要通訊的索引信息,我將轉到文件的第13位並讀取(不包括)第15位,換句話說,下一個單詞的偏移量。
對於靜態索引,這一切都很好。 但是,如果我更改單個索引,則整個文件將需要重寫。 我可以使用b樹作為索引文件的結構,以便可以動態更改文件內容並以某種方式更新偏移量嗎? 如果可以的話,有人可以指導我一些教程或庫是如何工作的,或者可以解釋一下我如何實現這一點?
非常感謝您抽出寶貴的時間閱讀這么長的文章。
編輯:我不知道B樹和二叉樹之間的區別。 所以我最初是用二叉樹問這個問題的。 現在已修復。
基本上,您正在嘗試建立反向索引。 為什么需要使用那么多文件? 您可以使用一個持久對象和字典來為您完成這項工作。 以后,當索引更改時,您只需重新加載持久對象並更改給定的條目並重新保存該對象即可。
這是執行此操作的示例代碼:
import shelve
DOC1 = "The problem of Programming Communication with"
DOC2 = "Programming of Arithmetic Operations"
DOC1 = DOC1.lower()
DOC2 = DOC2.lower()
all_words = DOC1.split()
all_words.extend(DOC2.split())
all_words = set(all_words)
inverted_index = {}
def location(doc, word):
return doc[:doc.find(word)].count(' ') + 1
for word in all_words:
if word in DOC1:
if word in inverted_index:
inverted_index[word].append(('DOC1', location(DOC1, word)))
else:
inverted_index[word] = [('DOC1', location(DOC1, word))]
if word in DOC2:
if word in inverted_index:
inverted_index[word].append(('DOC2', location(DOC2, word)))
else:
inverted_index[word] = [('DOC2', location(DOC2, word))]
# Saving to persistent object
inverted_index_file = shelve.open('temp.db')
inverted_index_file['1'] = inverted_index
inverted_index_file.close()
然后,您可以看到這樣保存的對象(您可以使用相同的策略對其進行修改):
>>> import shelve
>>> t = shelve.open('temp.db')['1']
>>> print t
{'operations': [('DOC2', 4)], 'of': [('DOC1', 3), ('DOC2', 2)], 'programming': [('DOC1', 4), ('DOC2', 1)], 'communication': [('DOC1', 5)], 'the': [('DOC1', 1)], 'with': [('DOC1', 6)], 'problem': [('DOC1', 2)], 'arithmetic': [('DOC2', 3)]}
我的觀點是,一旦您構建了該代碼一次,而其他代碼正在運行,則可以將shelve
對象作為字典存儲在內存中,並對其進行動態更改。
如果它不適合您,那么我將支持使用數據庫,尤其是sqlite3
因為它是輕量級的。
一種選擇是使用字典來構建數據,並使用cPickle將其轉儲到文件中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.