2017-10-20 30 views
0

我试图做一个简单的位置索引,但有一些问题得到正确的输出。简单的内存位置倒排索引python

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

代码:

主FUNC -

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': []} 

我知道收集libarary和NLTK,但我主要是为了学习/实践的原因这样做。

+0

你已经得到了'枚举'退步的顺序。你想'索引,枚举项目(alist):' –

回答

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)]} 
>>> 
+0

谢谢,doc.split解决了它。正如其他人指出的,我误解了列举。顺便说一句,我从来没有见过setdefault之前,这是如何工作的? – arm93

+0

'setdefault'方法检查字典中的'key';如果存在,则返回值,否则使用提供的值设置键并返回该值。 – mshsayem

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你不是n发表了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中,它将添加它并将其值初始化为空列表。否则,它只会追加到现有的列表中。

+0

谢谢你指出,tbh我把alist [项目]错误,但我被defo列举困惑。尽管现在你已经说过了,但由于某种原因,我认为它可以对单个单词进行迭代! – arm93

+0

也感谢您的额外提示。我知道默认字典,但是当我练习某种新东西时,我喜欢重新发明轮子,所以我知道100%程序中发生了什么。但是,我不知道defaultdict是否添加了该词,如果它不在那里。 – arm93