0

有一些文档需要索引,这意味着我需要阅读文档并提取单词并通过存储它们出现在哪个文档和哪个位置来索引它们。

对于每个单词,我最初创建一个单独的文件。考虑 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 个文档-第 3 个位置和第 2 个文档-第 2 个位置。

完成初始索引后,我会将所有文件连接到一个索引文件中,并在另一个文件中存储将找到特定单词的偏移量。

索引文件:

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-tree 作为索引文件的结构,以便我可以动态更改文件内容并以某种方式更新偏移量吗?如果是这样,有人可以指导我一些教程或库这是如何工作的,或者解释一下我如何实现这个?

非常感谢您花时间阅读这么长的帖子。

编辑:我不知道 B-tree 和二叉树之间的区别。所以我最初使用二叉树问了这个问题。现在已修复。

4

2 回答 2

1

基本上你正在尝试建立一个倒排索引。为什么需要使用这么多文件?您可以使用持久对象和字典来为您完成这项工作。稍后,当索引更改时,您只需重新加载持久对象并更改给定条目并重新保存对象。

这是执行此操作的示例代码:

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因为它是轻量级的。

于 2012-04-21T16:23:10.837 回答
0

一种选择是使用 dicts 来构造数据并使用 cPickle 将其转储到文件中。

于 2012-04-20T20:33:07.737 回答