1. 程式人生 > >python倒排索引

python倒排索引

一. 實驗目的

1.掌握列表、集合和字典的定義、賦值、使用等基本操作,熟悉處理複雜資料型別的一般流程
2.熟悉列表、集合和字典的常用函式和技巧
3.考察對文字的靈活處理和對排序演算法的運用

二. 實驗內容

倒排索引(Inverted index),也常被稱為反向索引,是一種索引方法,用來儲存某個單詞存在於哪些文字之中。是資訊檢索系統中最常用的資料結構。通過倒排索引,可以根據單詞快速獲取包含這個單詞的文件列表。

本實驗主要完成以下三個功能:

(1). 建立索引:首先輸入100行字串,用於構建倒排索引,每行字串由若干不含標點符號的、全部小寫字母組成的單詞構成,每個單詞之間以空格分隔。依次讀入每個單詞,並組成一個由<單詞, 每個單詞出現的行號集合>構成的字典,其中行號從1開始計數。

(2). 列印索引:按照字母表順序依次輸出每個單詞及其出現的位置,每個單詞出現的位置則按行號升序輸出。例如,如果“created”出現在第3, 20行,“dead”分別出現在14, 20, 22行。則輸出結果如下(冒號和逗號後面都有一個空格,行號不重複):

…

created: 3, 20

dead: 14, 20, 22

…

(3). 檢索:接下來輸入查詢(Query)字串,每行包含一個查詢,每個查詢由若干關鍵字(Keywords)組成,每個關鍵字用空格分隔且全部為小寫字母單詞。要求輸出包含全部單詞行的行號(升序排列),每個查詢輸出一行。若某一關鍵字在全部行中從沒出現過或沒有一行字串包含全部關鍵字,則輸出“None”。遇到空行表示查詢輸入結束。如對於上面建立的索引,當查詢為“created”時,輸出為“3, 20”;當查詢為“created dead”時,輸出為“20”;當查詢為“abcde dead”時,輸出為“None”;

(4). 高階檢索:當輸入的Query以“AND:”開始,則執行“與”檢索,即要求輸出包含全部關鍵字的行;如果輸入的Query以“OR:”開始,則執行“或”檢索,即某行只要出現了一個關鍵字就滿足條件。預設情況(不以“AND:”或“OR:”開始),執行“與”檢索。

解題思路

題目的意思和主要完成的思路已經講的很明白了:就是先給你100行句子建個字典,然後列印字典,最後查字典。查字典工作包括兩種查法:AND查詢和OR查詢,AND查詢操作其實就是集合的交,OR查詢就是集合的並。題目裡的“(3).檢索”就是AND查詢。

具體實現及出現問題

建立字典:我使用的是字典這種儲存結構,我用前100行中所有單詞作為key,values則是一個儲存每個單詞出現行數的集合

列印字典:因為要輸出符合字典序的字典,所以要用到python自帶的排序函式,注意排序的結果是個list(索引值是key,索引結果是set的列表形式),然後就可以愉快的列印了

查詢:AND查詢是集合的交,OR查詢是集合的並。所以我建字典的時候很機智的用了set作為values。

邊界情況:查詢的時候有空格行;

出現過的問題:

對字典進行排序之後,預設把所有set,dictionary……都變成list。
s = ‘空格’ s.split()的結果是[空] s.spilt(空格)的結果是[空格,空格]

程式碼:

# -*- coding: utf-8 -*-
"""
Created on Sat Nov 22 09:57:06 2014

@author: Liyu Fu
"""
'''Step one:New Dictionary'''
dict1 = {}
for i in range(100):
    sentence = raw_input()
    word_list = sentence.split()
    for
word in word_list: if word not in dict1: dict1[word] = set() #new word dict1[word].add(i+1) #update for dictionary '''Step two:Print Index''' answer_list = sorted(dict1.iteritems(),key=lambda d:d[0])#Sort by keyword of dictionary. for word in answer_list: l = list(word[1]) l.sort() print word[0]+': '+', '.join(map(str,l)) #Print Index def print_answer(answer_set): #Output search results empty_set = set() if empty_set == answer_set: #answer_set is empty print 'None' else: answer_list=list(answer_set) answer_list.sort() print ', '.join(map(str,answer_list)) #Print answer of Query '''Step three:Retrieval''' while True: Query = raw_input() if Query == '': break #Exit condition answer_set = set() if 'OR:' in Query: #OR-Retrieval Query = Query[3:] Q_word_list = Query.split() for word in Q_word_list: if (word != '')and(word in dict1): answer_set = dict1[word]|answer_set #set or print_answer(answer_set) else: #AND-Retrieval if 'AND:' in Query:Query = Query[4:] Q_word_list = Query.split() if Q_word_list!=[]: for i in range(1,101):answer_set.add(i) for word in Q_word_list: if (word != ''): if word in dict1: answer_set = dict1[word]&answer_set #set and else:answer_set = set() #wrong word print_answer(answer_set) else:print 'None'