Python 在txt中从字典中搜索单词并返回值 我的函数应该在文本中从字典中查找单词,然后在“points”变量中一起添加值。
但我把事情搞砸了。我的过程如下:Python 在txt中从字典中搜索单词并返回值 我的函数应该在文本中从字典中查找单词,然后在“points”变量中一起添加值。,python,python-3.x,function,dictionary,Python,Python 3.x,Function,Dictionary,但我把事情搞砸了。我的过程如下: 字典: words = {'very funny': 3,'funny': 2,'accidentally funny': 1} 文本文件(名为:sample.txt): 巨蟒很有趣+3 有些站姿很有趣+2 政客有时会意外地变得滑稽可笑+1 真正的蟒蛇一点也不好笑+二, *这些值表示我希望为每一行获得的分数 从.txt文件中获取文本: with open('sample.txt', 'r') as text: data = text.read(
words = {'very funny': 3,'funny': 2,'accidentally funny': 1}
有些站姿很有趣+2
政客有时会意外地变得滑稽可笑+1
真正的蟒蛇一点也不好笑+二, *这些值表示我希望为每一行获得的分数
with open('sample.txt', 'r') as text:
data = text.read()
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)
0
Process finished with exit code 0
“搞笑”:2
效果。不过我不知道该怎么做这是我关于堆栈的第一个问题,所以如果我把事情搞砸了,请告诉我。
对于数据中的I
,这就是问题所在。由于数据是一个str
,您基本上是在遍历单个字符,而不是完整的单词。我建议您反转您的逻辑-遍历术语并计算它们出现的次数:
def counter(data): #this should find keywords
points = 0
for word, value in words.items():
points += value * data.count(word)
print(points)
return points
然而,这意味着一些术语可以得分不止一次——“非常有趣”
也包含“有趣”
,所以它应该值5分(3分来自“非常有趣”
,2分来自“有趣”
)
您的文本包含4个
有趣
、1个非常有趣
和1个意外有趣
,因此结果是4*2+3+1=12这里的问题是您的数据结构。一般来说,如果你想查字典,字典是好的。然而,这不是你在这里要做的。相反,我建议使用一个元组列表。因此,您的单词将如下所示:
words = [ ("very funny", 3), ("funny", 2), ("accidentally funny", 1) ]
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]
接下来,当您运行for循环时,您将迭代字符串中的每个字符,而不是每个单词。您应该做的是迭代单词中的值,并找到每个单词出现的次数:
import re
total = 0
for w in words:
total += w[1] * sum(re.finditer(w[0], 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], '')
然而,这并不是很有效。如果你想让它跑得更快,我会使用一个。基本上,您可以将数据拆分为空白,并对其进行迭代,提取下一个k
字符,其中k
是words
中最长条目中的字数。您可以使用空格将这些k
单词连接在一起,并检查它们是否匹配words
中的任何条目。在这种情况下,顺便说一句,你可能想用字典。你可以这样做:
words = [ ("very funny", 3), ("funny", 2), ("accidentally funny", 1) ]
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 = {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++
words={1:{“有趣”:2},2:{“非常有趣”:3,“意外有趣”:1}
splitData=data.split('\r\n')
总数=0
i=0
而(i
请注意,我将l
添加到I
,以避免重复。同样,您可以使用元组而不是字典来声明搜索顺序。另外,我在这里使用while循环而不是forloop,因为在Python中,实际上无法更改循环中循环不变量的值。这就是我要做的。我把这篇文章分成一个单词列表,然后在上面迭代。我将每个单词与前面的一个连接起来。然后在字典里查两个单词的东西。当然,我不能将第一个单词与它前面的单词连接起来。所以first_iteration变量只在第一次迭代时为true,在第一次迭代结束时变为false,变为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)
因为第一个问题是一个很好的解释:你输入的预期输出是什么?@Austin我希望第一行的分数是+3,第二行的分数是+2,第三行的分数是+1,第四行的分数是+2=8是的,问题是我想把它从“非常有趣”和“意外有趣”中分离出来,算作一个“有趣”的单独数字。我应该在邮件里写。很快就会编辑的。看起来不错!我会尽快试试这个。谢谢你一步一步地解释。这很有帮助。@noobcodes如果这个解决方案有帮助,我建议使用upvoting。不只是对我来说,但总的来说。我会尽快检查它,一旦我得到15个代表。我们新手在那之前不能投票@noobcodes我还建议在你想列为问题“解决方案”的答案上打勾。不一定是我的,但这有助于其他用户在将来查看您的问题:)在介绍LL解析器之前的部分中,我得到以下信息:total+=len(re.finditer(w[0],data))*w[1]
TypeError:type'callable\u iterator'的对象没有len()