从txt中的字典中搜索单词并返回值

时间:2018-09-13 17:43:39

标签: python python-3.x function dictionary

我的函数应该从字典中的文本中查找单词,然后在“ points” 变量中添加值。

但是我搞砸了。我的过程如下:

  1. 词典:

    words = {'very funny': 3,'funny': 2,'accidentally funny': 1}  
    
  2. 文本文件(称为:sample.txt):

  

Monty Python非常有趣。 +3
  一些站起来很有趣。 +2
  政客有时会偶然地变得有趣。 +1
  真正的python一点都不有趣。 +2

*这些值代表我想为每一行获得的分数

  1. 从.txt文件中提取文本:

    with open('sample.txt', 'r') as text:
        data = text.read()
    
  2. 功能:

    def counter(data): #this should find keywords
        default_value = 0 #var for stuff not included in dict
        points = 0 
        for i in data:
            points += words.get(i, default_value)  #using get to avoid valueError
        print(points)
        return points  
    
    counter(data)
    
  3. 输出:

    0  
    
    Process finished with exit code 0
    

编辑我知道我忘记了什么;]

问题

  1. 我的功能似乎还不算什么
  2. 我想对这些关键的错误进行评分,以使单个单词“ funny”不会被三重评分,而只会触发'funny': 2效果。我不知道该如何处理。

这是我的第一个问题,因此,如果我搞砸了,请告诉我。

2 个答案:

答案 0 :(得分:0)

这里的问题是您的数据结构。通常,如果您要查找字典,字典是很好的选择。但是,这不是您在这里所做的。相反,我建议列出一个元组。因此,您的words如下所示:

words = [ ("very funny", 3), ("funny", 2), ("accidentally funny", 1) ]

接下来,当您运行for循环时,您要遍历字符串中的每个字符而不是每个单词。相反,您应该对words中的值进行迭代并找到每个单词出现的次数:

import re

total = 0
for w in words:
    total += w[1] * sum(re.finditer(w[0], data))

但是,正如已经指出的那样,它将找到重复项。为避免这种情况,应按要搜索它们的顺序对words进行排序,并从data中删除找到的值:

words = [ ("very funny", 3), ("accidentally funny", 1), ("funny", 2) ]

total = 0
for w in words:
    total += len(list(re.finditer(w[0], data))) * w[1]
    data = data.replace(w[0], '')

但是,这不是很出色。如果您想使其运行更快,我将使用LL parser。基本上,您将在空白上分割数据,然后对其进行迭代,然后拉下下一个k字符,其中kwords中最长条目中的单词数。您可以使用空格将这些k词连接在一起,并检查它们是否与words中的任何条目匹配。在这种情况下,您可能想使用字典。您可以这样:

splitData = data.split(' \r\n')
total = 0
for i in range(0, len(splitData)):

    # Longest entry in words has two words so we use i + 2
    phrase = ' '.join(splitData[i:(i + 2)])
    if (phrase in words):
        total += words[phrase]

当然,此解决方案假定所有条目中都包含两个单词,事实并非如此。要解决此问题,请将words制成词典字典,顶级字典将短语映射到其包含的单词数:

words = {1: {"funny": 2}, 2: {"very funny": 3, "accidentally funny": 1}}
splitData = data.split(' \r\n')
total = 0
i = 0
while (i < len(splitData)):
    for l, mapping in words.items():
        phrase = ' '.join(splitData[i:(i + l)])
        if (phrase in mapping):
            total += mapping[phrase]
            i += 1
            continue
    i++

请注意,我在l中添加了i,以避免重复。同样,您可以使用元组而不是字典来声明搜索顺序。另外,我在这里使用while循环而不是forloop,因为您实际上无法在Python的循环内更改循环不变式的值。

答案 1 :(得分:0)

这就是我要做的。我将文本分割成单词列表,然后对其进行迭代。我将每个单词与前面的单词连接在一起。然后在字典中查找两个单词的东西。当然,我不能将第一个单词与前面的单词连接在一起。因此,first_iteration变量仅在第一次迭代中为true,并且在第一次迭代结束时变为false。 我希望这能解决您的问题。

def counter(data): #this should find keywords
    default_value = 0 #var for stuff not included in dict
    points = 0 
    first_iteration = True
    wordsList = data.split()
    for i in wordList:
        if (!first_iteration):
            theWord = i + " " + prev
        points += words.get(theWord, default_value)  #using get to avoid valueError
        prev = i
        first_iteration = False
    print(points)
    return points  

counter(data)