2017-10-20 35 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