【问题标题】:How to count bigrams in several inputs in python如何在python的几个输入中计算二元组
【发布时间】:2018-05-21 14:47:29
【问题描述】:

在开始之前,以下是我的学习资料(Grok Learning,Python)中的确切说明 “编写一个程序来读取来自用户的多行输入,其中每一行是一个以空格分隔的单词句子。然后,您的程序应该计算每个二元组在所有输入句子中出现的次数。二元组应该是通过将输入行转换为小写以不区分大小写的方式进行处理。一旦用户停止输入输入,您的程序应打印出出现多次的每个二元组及其对应的频率。"

我应该在几个输入中找到二元组,我已经制定了这段代码。这段代码通过询问输入直到输入为空,然后将整行添加到一个名为组合的列表中,在此将其转换为这种格式的二元组 [('this', 'is'), ('is', ' a')] 等于称为文本的列表。现在,名为 text 的列表被转换为这种格式的简单二元组 [('this is'), ('is a')] 到另一个名为 newlist 的列表中。然后我将所有重复的字符串添加到一个名为 my_dict 的字典中并添加它们。我将它们打印在单独的行中,以便它可以生成每个二元组以及它的频率,不包括只出现一次的二元组。这是我的代码:

newlist = []
combined = []
a = (input("Line: ")).lower()
while a:
  combined.append(a)
  text = [b for l in combined for b in zip(l.split(" ")[:-1], l.split(" ")[1:])]
  a = (input("Line: ")).lower()
for bigram in text:
  newbigram = ' '.join(bigram)
  newlist.append(newbigram)
my_dict = {i:newlist.count(i) for i in newlist}
for words in sorted(my_dict):
  if my_dict[words] > 1:
    print(str(words) + str(": ") + str(my_dict[words]))

这是我的输出:

Line: The big red ball
Line: The big red ball is near the big red box
Line: I am near the box
Line: 
big red: 3
near the: 2
red ball: 2
the big: 3

看到这段代码运行良好,但是每当我设置一个空值时,它都会出现以下错误消息:

Line: 
Traceback (most recent call last):
  File "program.py", line 8, in <module>
    for bigram in text:
NameError: name 'text' is not defined

为什么会这样,我该如何解决?

【问题讨论】:

  • 空字符串不是真实。因此,您无需进入 while 循环并定义 text
  • 提示:当a为空时,while a:块(包括text = ...语句)会运行多少次?
  • 在开头使用text = []。所以text 是在你有值或设置空值的情况下定义的。

标签: python


【解决方案1】:

您的主要问题是由于 empty 输入实际上包含 \n 的值,因此您的 while 语句评估为 True。您可以剥离用户输入,以便不包含尾随/前导空格,因为无论如何它对您的使用都是无关紧要的,例如:

a = input("Line: ").strip().lower()

如果用户从不输入任何内容(只有一个空行),您的 text 列表将永远不会被初始化,因此请在您的 while 循环之前对其进行初始化。

话虽这么说,但您对此过于复杂了 - 您只需要一个字典计数器并迭代输入的元组以增加计数,例如:

import collections

counter = collections.defaultdict(int)  # use a dictionary factory to speed up our counting
while True:
    line = input("Line: ").lower().split()  # lowercase and split on whitespace
    if not line:  # user entered an empty line
        break
    for bigram in zip(line, line[1:]):  # iterate over bigrams
        counter[bigram] += 1  # increase the count of each bigram
for bigram, count in counter.items():  # use counter.iteritems() on Python 2.x
    if count > 1:  # consider only bigrams with larger count than 1
        print("{} {}: {}".format(bigram[0], bigram[1], count))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2020-01-12
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多