我目前正在尝试创建单词索引,从文本文件中读取每一行并检查该单词是否在该行中。如果是这样,它会打印出数字行并继续检查。在打印每个单词和行号时,我已经完成了我想要的工作,但我不确定我可以用什么存储系统来包含每个数字。
代码示例:
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]}
有什么想法吗?
答案 0 :(得分: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的Raven)。
或者,您可以考虑使用普通dict
而不是defaultdict
,并使用列表中的所有字词对其进行初始化;确保indexDict
包含条目,即使是不在文本中的单词。
另外,请注意enumerate
的使用。这个内置函数对于迭代索引和某个列表的索引处的项目(如文件中的行)非常有用。
答案 1 :(得分: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]}
答案 2 :(得分:2)
您正在用此行替换旧值
indexDict[word] = [count]
将其更改为
indexDict[word] = indexDict.setdefault(word, []) + [count]
会产生你想要的答案。它将获取indexDict [word]的当前值并将新计数附加到它,如果没有indexDict [word],它会创建一个新的空列表并向其追加计数。
答案 3 :(得分:1)
如果列表已存在,您需要将下一个项目附加到列表中。
即使是第一次找到单词,列表已经存在的最简单方法是使用collections.defaultdict
class来跟踪您的单词到行的映射:
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
(也是一组)的集合交集测试,可以更快地找到匹配的单词。