维基百科的Python倒置索引

时间:2014-02-04 21:35:46

标签: python

我正在查看维基百科的Inverted Indexes版本,我对“Python”版本特别感兴趣。 http://rosettacode.org/wiki/Inverted_index#Python 从本质上讲,代码的错误对我来说相当混乱。

编辑:由于2rs2ts的努力,代码现已修复。

from pprint import pprint as pp
from glob import glob
try: reduce
except: from functools import reduce
try:    raw_input
except: raw_input = input



def parsetexts(fileglob='*.txt'):
    texts, words = {}, set()
    for txtfile in glob(fileglob):
        with open(txtfile, 'r') as f:
            txt = f.read().split()
            words |= set(txt)
            texts[txtfile.split('\\')[-1]] = txt
    return texts, words

def termsearch(terms): # Searches simple inverted index
    return reduce(set.intersection,
                  (invindex[term] for term in terms),
                  set(texts.keys()))

texts, words = parsetexts()
print('\nTexts')
pp(texts)
print('\nWords')
pp(sorted(words))

invindex = {word:set(txt
                        for txt, wrds in texts.items() if word in wrds)
            for word in words}
print('\nInverted Index')
pp({k:sorted(v) for k,v in invindex.items()})

terms = ["what", "is", "it"]
print('\nTerm Search for: ' + repr(terms))
pp(sorted(termsearch(terms)))

现在,当我尝试运行T1.txt文件(按照指示)时发生错误(在Python 2.7和3.3中都出现)

Traceback (most recent call last):
  File "/Users/abcoleman/Documents/Intro2.py", line 38, in <module>
    pp(sorted(termsearch(terms)))
  File "/Users/abcoleman/Documents/Intro2.py", line 22, in termsearch
    set(texts.keys()))
  File "/Users/abcoleman/Documents/Intro2.py", line 21, in <genexpr>
    (invindex[term] for term in terms),
KeyError: 'what'

我正在犯一些愚蠢的错误吗?我的导师本人无法理解错误。

1 个答案:

答案 0 :(得分:0)

让我们向后看一下程序,以了解出了什么问题。您获得的例外情况意味着密钥'what'不在invindex中,但它位于terms中。这是有道理的,因为terms = ["what", "is", "it"]

  1. 'what'未添加到invindex导致异常。
  2. 反过来,使用列表invindex构建words,这意味着'what'不在words中。

    1. 'what'未添加到words
    2. invindex是由words构建的,因此'what'也未添加到invindex。这引起了例外。
    3. 由于words是使用texts, words = parsetexts()创建的,这意味着parsetexts()应该受到责备。

      1. 'what'未添加到words parsetexts()未将'what'添加到words
      2. invindex是由words构建的,因此'what'也未添加到invindex。这引起了例外。
      3. wordsset,行words |= set(txt)是联合操作,这意味着set(txt)中尚未包含words的任何内容添加。这意味着txt也不包含'what'txt是通过读取文件并分隔每个单词(由空格分隔)并将其放入列表中创建的。因此'what'不在parsetexts()迭代的任何文件中。

          'what'迭代的任何文件中找不到
        1. parsetexts()
        2. 'what'未添加到words parsetexts()未将'what'添加到words
        3. invindex是由words构建的,因此'what'也未添加到invindex。这引起了例外。
        4. 您说您使用的是名为T1.txt的文件,其中应包含'what'字样,对吧? (我假设它确实如此。)如果程序试图打开T1.txt,并且它不存在或不可读,那么你会收到IOError,所以这也不是问题。而且,如果您使用的唯一文件是T1.txt(我再次假设这是问题),则必须是程序未打开T1.txt

          罪魁祸首是执行glob。因此文件说:

            

          返回一个可能为空的路径名列表,该路径名与路径名匹配,路径名必须是包含路径规范的字符串。

          这意味着您指定的glob不包含T1.txt。由于这是你使用的唯一文件,因此glob可能没有包含任何内容。您可以print glob(fileglob)或仅在print循环的开头添加for语句来验证这一点,看看你得到了什么 - 如果没有包含任何文件glob,后一种方法将导致print编辑。

          1. parsetexts()没有迭代任何文件,因为glob(fileglob)没有返回任何内容。 (或者,它可能没有包含T1.txt。)
          2. 'what'迭代的任何文件中找不到
          3. parsetexts()
          4. 'what'未添加到words parsetexts()未将'what'添加到words
          5. invindex是由words构建的,因此'what'也未添加到invindex。这引起了例外。
          6. 你去吧! print是你的朋友:)