简单的内存位置倒排索引在python中

时间:2017-10-20 17:45:35

标签: python

我试图制作一个简单的位置索引但是在获得正确输出时遇到一些问题。

给定一个字符串(句子)列表,我想使用sting列表中的字符串位置作为文档id,然后迭代句子中的单词并使用句子中的单词index作为其位置。然后使用doc id的元组及其在doc中的位置更新单词词典。

代码:

主要功能 -

def doc_pos_index(alist):
    inv_index= {}
    words = [word for line in alist for word in line.split(" ")]

    for word in words:
        if word not in inv_index:
            inv_index[word]=[]

    for item, index in enumerate(alist): # find item and it's index in list
        for item2, index2 in enumerate(alist[item]): # for words in string find word and it's index
            if item2 in inv_index:
                inv_index[i].append(tuple(index, index2)) # if word in index update it's list with tuple of doc index and position

    return inv_index 

示例列表:

doc_list= [
'hello Delivered dejection necessary objection do mr prevailed',
'hello Delivered dejection necessary objection do mr prevailed',
'hello Delivered dejection necessary objection do mr prevailed',
'hello Delivered dejection necessary objection do mr prevailed',
'hello Delivered dejection necessary objection do mr prevailed'
]

期望的输出:

{'Delivered': [(0,1),(1,1),(2,1),(3,1),(4,1)],
'necessary': [(0,3),(1,3),(2,3),(3,3),(4,3)], 
'dejection': [(0,2),(1,2),(2,2),(3,2),(4,2)],
 ect...}

当前输出:

{'Delivered': [],
'necessary': [], 
'dejection': [], 
'do': [],
'objection': [], 
'prevailed': [], 
'mr': [], 
'hello': []}

一个fyi,我确实知道收藏图书馆和NLTK,但我主要是出于学习/练习的原因这样做。

2 个答案:

答案 0 :(得分:1)

检查一下:

>>> result = {}
>>> for doc_id,doc in enumerate(doc_list):
        for word_pos,word in enumerate(doc.split()):
            result.setdefault(word,[]).append((doc_id,word_pos))


>>> result
{'Delivered': [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)], 'necessary': [(0, 3), (1, 3), (2, 3), (3, 3), (4, 3)], 'dejection': [(0, 2), (1, 2), (2, 2), (3, 2), (4, 2)], 'do': [(0, 5), (1, 5), (2, 5), (3, 5), (4, 5)], 'objection': [(0, 4), (1, 4), (2, 4), (3, 4), (4, 4)], 'prevailed': [(0, 7), (1, 7), (2, 7), (3, 7), (4, 7)], 'mr': [(0, 6), (1, 6), (2, 6), (3, 6), (4, 6)], 'hello': [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)]}
>>> 

答案 1 :(得分:1)

您似乎对enumerate的作用感到困惑。 enumerate()返回的第一个项是索引,第二个项是值。你似乎已经逆转了。

您对第二次使用enumerate()

感到困惑
for item2, index2 in enumerate(alist[item]): # for words in string find word and it's index

首先,您不需要alist[item]。你已经在index变量中拥有该行的值(同样,你可能会因为你的变量名向后而感到困惑。其次,你似乎认为enumerate()会将一行划分为单个单词它不会。但它会迭代字符串中的每个字符(我很困惑你为什么这么想,因为你之前证明过你知道如何拆分字符串空间 - 虽然很有趣。

作为补充提示,您不需要这样做:

for word in words:
    if word not in inv_index:
        inv_index[word]=[]

首先,由于您只是初始化dict,因此您不需要if声明。刚

for word in words:
    inv_index[word] = []

会做的。如果单词已经在字典中,这将进行不必要的分配,是真的,但它仍然是O(1)操作,所以没有坏处。但是,您甚至不需要这样做。相反,您可以使用collections.defaultdict

from collections import defaultdict
inv_index = defaultdict(list)

然后你可以做ind_index[word].append(...)。如果word中尚未显示inv_index,则会将其添加并将其值初始化为空列表。否则它只会附加到现有列表中。