【问题标题】:Print 10 most infrequent words of a text document using python使用 python 打印文本文档中 10 个最不常用的单词
【发布时间】:2012-09-17 10:08:47
【问题描述】:

我有一个小的 Python 脚本,可以打印文本文档中最常用的 10 个单词(每个单词为 2 个或更多字母),我需要继续执行该脚本以打印文档中最不常用的 10 个单词。我有一个相对有效的脚本,除了它打印的 10 个最不常见的单词是数字(整数和浮点数),而它们应该是单词。如何仅迭代单词并排除数字?这是我的完整脚本:

# Most Frequent Words:
from string import punctuation
from collections import defaultdict

number = 10
words = {}

with open("charactermask.txt") as txt_file:
    words = [x.strip(punctuation).lower() for x in txt_file.read().split()]

counter = defaultdict(int)

for word in words:
  if len(word) >= 2:
    counter[word] += 1

top_words = sorted(counter.iteritems(),
                    key=lambda(word, count): (-count, word))[:number] 

for word, frequency in top_words:
    print "%s: %d" % (word, frequency)


# Least Frequent Words:
least_words = sorted(counter.iteritems(),
                    key=lambda (word, count): (count, word))[:number]

for word, frequency in least_words:
    print "%s: %d" % (word, frequency)

编辑:文档的结尾(# Least Frequent Words 注释下的部分)是需要修复的部分。

【问题讨论】:

    标签: python python-2.6 defaultdict


    【解决方案1】:

    您将需要一个过滤器 - 更改正则表达式以匹配但是您想定义一个“单词”:

    import re
    alphaonly = re.compile(r"^[a-z]{2,}$")
    

    现在,您是否希望词频表一开始就不包含数字

    counter = defaultdict(int)
    
    with open("charactermask.txt") as txt_file:
        for line in txt_file:
            for word in line.strip().split():
              word = word.strip(punctuation).lower()
              if alphaonly.match(word):
                  counter[word] += 1
    

    或者您只是想在从表格中提取最不常用的单词时跳过数字

    words_by_freq = sorted(counter.iteritems(),
                           key=lambda(word, count): (count, word))
    
    i = 0
    for word, frequency in words_by_freq:
        if alphaonly.match(word):
            i += 1
            sys.stdout.write("{}: {}\n".format(word, frequency))
        if i == number: break
    

    【讨论】:

      【解决方案2】:

      您需要一个函数letters_only(),它将运行匹配[0-9] 的正则表达式,如果找到任何匹配项,则返回False。像这样的::

      def letters_only(word):
          return re.search(r'[0-9]', word) is None
      

      然后,你说for word in words,而不是说for word in filter(letters_only, words)

      【讨论】:

      • 太棒了。还将我的答案更改为 wim 建议的较短形式;我认为较长的形式更清晰,但也许它只是我需要驱除的代码tic。 :) 对否决票有点困惑,但事实就是如此。
      猜你喜欢
      • 2018-01-28
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      相关资源
      最近更新 更多