0

我目前正在尝试创建单词索引,从文本文件中读取每一行并检查单词是否在该行中。如果是这样,它会打印出数字行并继续检查。在打印每个单词和行号时,我已经让它按我想要的方式工作,但我不确定我可以使用什么存储系统来包含每个数字。

代码示例:

def index(filename, wordList):
    'string, list(string) ==> string & int, returns an index of words with the line number\
    each word occurs in'
    indexDict = {}
    res = []
    infile = open(filename, 'r')
    count = 0
    line = infile.readline()
    while line != '':
        count += 1
        for word in wordList:
            if word in line:
                #indexDict[word] = [count]
                print(word, count)
        line = infile.readline()
    #return indexDict

这会打印单词以及当时的计数(行号),但我要做的是存储数字,以便稍后我可以打印出来

word linenumber

word2 linenumber, linenumber

等等。如果我将每个行号放在一个列表中,我觉得字典可以解决这个问题,这样每个键可以包含多个值,但我得到的最接近的是:

{'mortal': [30], 'dying': [9], 'ghastly': [82], 'ghost': [9], 'raven': [120], 'evil': [106], 'demon': [122]}

当我希望它显示为:

{'mortal': [30], 'dying': [9], 'ghastly': [82], 'ghost': [9], 'raven': [44, 53, 55, 64, 78, 97, 104, 111, 118, 120], 'evil': [99, 106], 'demon': [122]}

有任何想法吗?

4

4 回答 4

3

尝试这样的事情:

import collections
def index(filename, wordList):
    indexDict = collections.defaultdict(list)
    with open(filename) as infile:
        for (i, line) in enumerate(infile.readlines()):
            for word in wordList:
                if word in line:
                    indexDict[word].append(i+1)
    return indexDict

这会产生与您的示例完全相同的结果(使用 Poe's Raven)。

或者,您可以考虑使用 normaldict而不是 adefaultdict并使用列表中的所有单词对其进行初始化;确保indexDict即使对于不在文本中的单词也包含条目。

另外,请注意enumerate. 这个内置函数对于迭代某个列表的索引和该索引处的项目(如文件中的行)非常有用。

于 2013-03-10T21:17:02.367 回答
2

可能有一种更 Pythonic 的方式来编写它,但只是为了便于阅读,你可以试试这个(一个简单的例子):

dict = {1: [], 2: [], 3: []}

list = [1,2,2,2,3,3]

for k in dict.keys():
    for i in list:
        if i == k:
            dict[k].append(i)


In [7]: dict
Out[7]: {1: [1], 2: [2, 2, 2], 3: [3, 3]}
于 2013-03-10T21:19:27.887 回答
2

您正在用这一行替换旧值

indexDict[word] = [count]

将其更改为

indexDict[word] = indexDict.setdefault(word, []) + [count]

Will yield the answer you want. It'll get the current value of indexDict[word] and append the new count to it, if there is no indexDict[word], it creates a new empty list and append count to it.

于 2013-03-10T21:20:56.283 回答
1

如果列表已经存在,您需要将下一个项目附加到列表中。

即使是第一次找到一个单词,让列表已经存在的最简单方法是使用collections.defaultdict该类来跟踪您的单词到行的映射:

from collections import defaultdict

def index(filename, wordList):
    indexDict = defaultdict(list)
    with open(filename, 'r') as infile:
        for i, line in enumerate(infile):
            for word in wordList:
                if word in line:
                    indexDict[word].append(i)
                    print(word, i)

    return indexDict

我使用最佳实践稍微简化了您的代码;作为上下文管理器打开文件,这样它会在完成后自动关闭,并enumerate()用于动态创建行号。

set(line.split())如果你将你的行变成一组单词(也许,但这不会删除标点符号),你可以进一步加快速度(并使其更准确) ,因为那时你可以使用集合交集测试来对抗wordList(也是set),这样可以更快地找到匹配的单词。

于 2013-03-10T21:20:04.740 回答