【问题标题】:Python program that finds most frequent word in a .txt file, Must print word and its count在 .txt 文件中查找最常见单词的 Python 程序,必须打印单词及其计数
【发布时间】:2020-04-05 15:36:33
【问题描述】:

截至目前,我有一个函数可以替换 countChars 函数,

def countWords(lines):
  wordDict = {}
  for line in lines:
    wordList = lines.split()
    for word in wordList:
      if word in wordDict: wordDict[word] += 1
      else: wordDict[word] = 1
  return wordDict

但是当我运行程序时,它吐出了这个可憎的东西(这只是一个例子,大约有两页字,旁边有大量的数字)

before 1478
battle-field 1478
as 1478
any 1478
altogether 1478
all 1478
ago 1478
advanced. 1478
add 1478
above 1478

虽然这显然意味着代码足够健全,可以运行,但我并没有从中得到我想要的东西。 它需要打印每个单词在文件中出现的次数(gb.txt,也就是葛底斯堡地址) 显然,文件中的每个单词都没有准确地出现 1478 次..

我对编程很陌生,所以我有点难过..

from __future__ import division

inputFileName = 'gb.txt'

def readfile(fname):
  f = open(fname, 'r')
  s = f.read()
  f.close()
 return s.lower()

def countChars(t):
  charDict = {}
  for char in t:
    if char in charDict: charDict[char] += 1
    else: charDict[char] = 1
  return charDict

def findMostCommon(charDict):
  mostFreq = ''
  mostFreqCount = 0
  for k in charDict:
    if charDict[k] > mostFreqCount:
      mostFreqCount = charDict[k]
      mostFreq = k
  return mostFreq

def printCounts(charDict):
  for k in charDict:
    #First, handle some chars that don't show up very well when they print
    if k == '\n': print '\\n', charDict[k]  #newline
    elif k == ' ': print 'space', charDict[k]
    elif k == '\t': print '\\t', charDict[k] #tab
    else: print k, charDict[k]  #Normal character - print it with its count

def printAlphabetically(charDict):
  keyList = charDict.keys()
  keyList.sort()
  for k in keyList:
    #First, handle some chars that don't show up very well when they print
    if k == '\n': print '\\n', charDict[k]  #newline
    elif k == ' ': print 'space', charDict[k]
    elif k == '\t': print '\\t', charDict[k] #tab
    else: print k, charDict[k]  #Normal character - print it with its count

def printByFreq(charDict):
  aList = []
  for k in charDict:
    aList.append([charDict[k], k])
  aList.sort()     #Sort into ascending order
  aList.reverse()  #Put in descending order
  for item in aList:
    #First, handle some chars that don't show up very well when they print
    if item[1] == '\n': print '\\n', item[0]  #newline
    elif item[1] == ' ': print 'space', item[0]
    elif item[1] == '\t': print '\\t', item[0] #tab
    else: print item[1], item[0]  #Normal character - print it with its count

def main():
  text = readfile(inputFileName)
  charCounts = countChars(text)
  mostCommon = findMostCommon(charCounts)
  #print mostCommon + ':', charCounts[mostCommon]
  #printCounts(charCounts)
  #printAlphabetically(charCounts)
  printByFreq(charCounts)

main()

【问题讨论】:

    标签: python


    【解决方案1】:

    如果你需要计算一篇文章中的单词数,那么最好使用正则表达式。

    让我们从一个简单的例子开始:

    import re
    
    my_string = "Wow! Is this true? Really!?!? This is crazy!"
    
    words = re.findall(r'\w+', my_string) #This finds words in the document
    

    结果:

    >>> words
    ['Wow', 'Is', 'this', 'true', 'Really', 'This', 'is', 'crazy']
    

    请注意,“是”和“是”是两个不同的词。我的猜测是,您希望 对它们进行相同的计数,因此我们可以将所有单词大写,然后计算它们。

    from collections import Counter
    
    cap_words = [word.upper() for word in words] #capitalizes all the words
    
    word_counts = Counter(cap_words) #counts the number each time a word appears
    

    结果:

    >>> word_counts
    Counter({'THIS': 2, 'IS': 2, 'CRAZY': 1, 'WOW': 1, 'TRUE': 1, 'REALLY': 1})
    

    你还好吗?

    现在我们需要做与我们在上面读取文件时完全相同的事情。

    import re
    from collections import Counter
    
    with open('your_file.txt') as f:
        passage = f.read()
    
    words = re.findall(r'\w+', passage)
    
    cap_words = [word.upper() for word in words]
    
    word_counts = Counter(cap_words)
    

    【讨论】:

    • 哇。虽然这可能不是我的教授希望我们使用的方法,但这非常适合查找数字计数。在这一点上,我最好需要得到它们,以便它们打印在一个列中以提高可读性。作业也有几个部分,其中包括: 仅打印最常用的单词。按字母顺序打印所有单词及其计数。然后按频率顺序打印所有单词及其计数。如果我没记错的话,这些都很简单,但我不知道我所学到的是否与您到目前为止给我的兼容。
    • 你提到的任务不是很困难,你需要使用.sort()sorted(),也许搜索如何排序字典。这是你的作业,是你做的;),但如果你在某些方面遇到困难,请发布你所拥有的(作为另一个问题),有人会帮助你。
    • 我可以在一行中添加一个passage = f.read().upper()
    【解决方案2】:

    如果你使用强大的工具,这个程序实际上是一个 4 行:

    with open(yourfile) as f:
        text = f.read()
    
    words = re.compile(r"[\w']+", re.U).findall(text)   # re.U == re.UNICODE
    counts = collections.Counter(words)
    

    正则表达式将查找所有单词,而不管与它们相邻的标点符号(但将撇号计为单词的一部分)。

    计数器的作用几乎就像字典一样,但您可以执行counts.most_common(10) 之类的操作,并添加计数等。请参阅help(Counter)

    我还建议你不要创建函数printBy...,因为只有没有副作用的函数才易于重用。

    def countsSortedAlphabetically(counter, **kw):
        return sorted(counter.items(), **kw)
    
    #def countsSortedNumerically(counter, **kw):
    #    return sorted(counter.items(), key=lambda x:x[1], **kw)
    #### use counter.most_common(n) instead
    
    # `from pprint import pprint as pp` is also useful
    def printByLine(tuples):
        print( '\n'.join(' '.join(map(str,t)) for t in tuples) )
    

    演示:

    >>> words = Counter(['test','is','a','test'])
    >>> printByLine( countsSortedAlphabetically(words, reverse=True) )
    test 2
    is 1
    a 1
    

    编辑以解决 Mateusz Konieczny 的评论:将 [a-zA-Z'] 替换为 [\w']... 字符类 \w,根据 python 文档,“匹配 Unicode 单词字符;这包括可以成为任何语言的单词一部分的大多数字符,以及数字和下划线。如果使用 ASCII 标志,则仅匹配 [a-zA-Z0-9_]。 (...但显然不匹配撇号...)但是 \w 包括 _ 和 0-9,所以如果你不想要这些并且你没有使用 unicode,你可以使用 [a-zA -Z'];如果你正在使用 unicode,你需要做一个否定断言或从 \w 字符类中减去 [0-9_] 的东西

    【讨论】:

    • 哎呀,我以为我提到过这是在 Python 2.7 中。
    • @ZachCorse collections.Counter
    • @ninjagecko 显然你知道你在做什么,但这似乎比我目前所学的要领先。我可能听起来很傻,但是当我尝试任何这些事情时,更具体地说是您发布的第一个,我收到这样的名称错误。 words = re.compile(r"a-zA-Z'").findall(text) NameError: name 're' is not defined
    • 尝试以import re 开头。 import collections 也可能有帮助。
    • words = re.compile(r"a-zA-Z'").findall(text) 对于 nonascii 文本已损坏(例如波兰语单词 - text="Zażółć gęślą jaźń"
    【解决方案3】:

    你有一个简单的错字,words,你想要word

    编辑:您似乎已经编辑了源代码。请使用复制和粘贴在第一时间正确完成。

    编辑 2: 显然你不是唯一一个容易出现拼写错误的人。真正的问题是你有lines 你想要line。对于指责您编辑源代码,我深表歉意。

    【讨论】:

    • 不确定您的意思。我用搜索单词的函数替换了搜索字符的函数,并替换了 main 函数中的一个单词,以便它可以运行。
    • 当我从行中删除 s 时,它只计算字符。编辑:糟糕,输入太快了。我需要它来计算文件中每个单词的数量。将小写的 s 附加到行上,它会查看有多少单词,但不会计算它们。 (有数字,但由于某种原因,它们大部分都相同)
    【解决方案4】:
     words = ['red', 'green', 'black', 'pink', 'black', 'white', 'black', 
    'eyes','white', 'black', 'orange', 'pink', 'pink', 'red', 'red', 
    'white', 'orange', 'white', "black", 'pink', 'green', 'green', 'pink', 
    'green', 'pink','white', 'orange', "orange", 'red']
    
     from collections import Counter
     counts = Counter(words)
     top_four = counts.most_common(4)
     print(top_four)
    

    【讨论】:

      【解决方案5】:

      这是一个可能的解决方案,虽然不像 ninjagecko 那样优雅,但仍然:

      from collections import defaultdict
      
      dicto = defaultdict(int)
      
      with open('yourfile.txt') as f:
          for line in f:
              s_line = line.rstrip().split(',') #assuming ',' is the delimiter
              for ele in s_line:
                  dicto[ele] += 1
      
       #dicto contians words as keys, word counts as values
      
       for k,v in dicto.iteritems():
           print k,v
      

      【讨论】:

      【解决方案6】:

      导入集合并定义函数

      from collections import Counter 
      def most_count(n):
        split_it = data_set.split() 
        b=Counter(split_it)  
        return b.most_common(n) 
      

      调用指定您想要的前 'n' 个单词的函数。在我的例子中 n=15

      most_count(15)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 2015-06-02
        • 2018-01-28
        相关资源
        最近更新 更多