如何计算段落中的单词数量并排除某些单词(来自文件)?

时间:2011-09-09 09:19:00

标签: python count text-mining

我刚开始学习Python,所以我的问题可能有点傻。我正在尝试创建一个程序:
- 导入文本文件(得到它)
- 计算单词总数(得到它),
- 计算特定段落中的单词数量,从特定短语开始(例如“P1”,以另一个参与者“P2”结尾),并从我的单词计数中排除这些单词。不知怎的,我最终得到了一些可以计算字符数的东西:/
- 单独打印段落(得到它)
- 从我的字数中排除“P1”“P2”等字。

我的文本文件如下所示:
P1:Bla bla bla。
P2:Bla bla bla bla。
P1:Bla bla。
P3:Bla。

我最终得到了这段代码:

text = open (r'C:/data.txt', 'r')
lines = list(text)
text.close()
words_all = 0
for line in lines:
    words_all = words_all + len(line.split())
print 'Total words:   ', words_all

words_par = 0
for words_par in lines:
    if words_par.startswith("P1" or "P2" or "P3") & words_par.endswith("P1" or "P2" or "P3"):
        words_par = line.split()
    print len(words_par)
    print words_par.replace('P1', '') #doesn't display it but still counts
else:
    print 'No words'

任何想法如何改进它?

由于

3 个答案:

答案 0 :(得分:2)

您不应使用标识符文字来致电open ('zery.txt', 'r')。它不是文件中的文本,它是文件的处理程序,在文档中描述为“文件类对象”(顺便说一下,我从不理解它的含义,“文件类对象”)

with open ('C:/data.txt', 'r')  as f:
    ........
    ........

优于

f = open ('C:/data.txt', 'r') 
    ......
    .....
f.close()

您应该阅读有关 split()的说明,这样您就可以看到:

with open ('C:/data.txt', 'r') as f:
    text = f.read()
words_all = len(text.split())
print 'Total words:   ', words_all

如果您的文字结构是:

P1: Bla bla bla. 
P2: Bla bla bla bla. 
P1: Bla bla. 
P3: Bla.

然后words_par.endswith("P1" or "P2" or "P3")总是 False ,因此不会执行所需的拆分。

因此, words_par 不会成为一个列表,它仍然是一个字符串,这就是字符计数的原因。

此外,您的代码肯定是错误的。

如果执行了拆分,它将是在代码开头的第一个for循环中获得的最后一个,它将被重复拆分。

所以,而不是

for words_par in lines: 
    if words_par.startswith("P1" or "P2" or "P3"):
        words_par = line.split() 

肯定是:

for line in lines: 
    if line[0:2] in ("P1","P2","P3") :
        words_par = line.split() 

答案 1 :(得分:2)

也许我完全不理解这些要求,但我会尽我所能。

关于计算所有单词的第一部分是相当不错的。我会稍微缩短一点:

with open('C:/data.txt', 'r') as textfile:
    lines = list(textfile)
words_all = sum([len(line.split()) for line in lines])
print 'Total words:   ', words_all

在第二部分,似乎出现了问题。

words_par = 0 # You can leave out this line,
              # 'words_par' is initialized in the for-statement

这里有更多问题:

    if words_par.startswith("P1" or "P2" or "P3") & words_par.endswith("P1" or "P2" or "P3"):

"P1" or "P2" or "P3"评估为"P1"(非空字符串为“真实”值)。所以你可以将线缩短到

    if words_par.startswith("P1") & words_par.endswith("P1"):

这可能不是你想要的。
当条件求值为False时,不调用split方法,words_par仍为字符串(而不是预期的字符串列表)。因此len(words_par)会返回字符数而不是字数。

(对名称有点不满:恕我直言,这个错误源于变量的不准确命名。不同的命名

for line in lines:
    if line.startswith(...:
        words_par = line.split()
    print len(words_par)

会产生明确的错误消息。在第二次阅读中,无论如何,这一定是你的意思。)

答案 2 :(得分:2)

第一部分是好的,你可以得到总单词并打印结果。

你跌倒的地方就在这里

words_par = 0
for words_par in lines:
    if words_par.startswith("P1" or "P2" or "P3") & words_par.endswith("P1" or "P2" or "P3"):
        words_par = line.split()
    print len(words_par)
    print words_par.replace('P1', '') #doesn't display it but still counts
else:
    print 'No words'

words_par 首先是一个包含文件行的字符串。在永远不会满足的条件下,它会变成带有

的列表
line.split()

表达。这个,如果表达式

words_par.startswith("P1" or "P2" or "P3") & words_par.endswith("P1" or "P2" or "P3")

永远都会返回True,因为上一次分配给你的文件的最后一行是在你的程序的第一部分,你在那里完全计算了单词的数量。文件。那应该是

words_par.split()

另外

words_par.startswith("P1" or "P2" or "P3")

永远是

words_par.startswith("P1")

因为

"P1" or "P2" or "P3"

始终计算为第一个为True,这是本例中的第一个字符串。如果您想了解更多信息,请阅读http://docs.python.org/reference/expressions.html

虽然我们在这,但除非你想做按位比较,否则不要做

something & something

代替

something and something

第一个将评估两个表达式,无论第一个表达式是什么,第二个表达式只评估第二个表达式,如果第一个表达式为True。如果你这样做,你的代码将更有效地运作。

print len(words_par)
下一行的

总是要计算行中的字符数,因为if语句总是要计算为False而且word_par永远不会被分成单词列表。

无论序列是否为空,for循环上的else子句也将始终执行。有关详细信息,请查看http://docs.python.org/reference/compound_stmts.html#the-for-statement

根据我的想法,我写了一个我认为你所追求的版本。我试图保持简单并避免使用列表理解之类的东西,因为你说你刚开始学习,所以它不是最优的,但希望很清楚。另请注意,我没有发表评论,所以请随时帮我解释一下。

words = None
with open('data.txt') as f:
    words = f.read().split()
total_words = len(words)
print 'Total words:', total_words

in_para = False
para_count = 0
para_type = None
paragraph = list()
for word in words:
  if ('P1' in word or
      'P2' in word or
      'P3' in word ):
      if in_para == False:
         in_para = True
         para_type = word
      else:
         print 'Words in paragraph', para_type, ':', para_count
         print ' '.join(paragraph)
         para_count = 0
         del paragraph[:]
         para_type = word
  else:
    paragraph.append(word)
    para_count += 1
else:
  if in_para == True:
    print 'Words in last paragraph', para_type, ':', para_count
    print ' '.join(paragraph)
  else:
    print 'No words'

编辑:

我实际上只注意到示例中的一些冗余代码。不需要变量para_count,因为单词被附加到段落变量。而不是

print 'Words in paragraph', para_type, ':', para_count

你可以做到

print 'Words in paragraph', para_type, ':', len(paragraph)

跟踪的少变量。这是更正的片段。

in_para = False
para_type = None
paragraph = list()
for word in words:
  if ('P1' in word or
      'P2' in word or
      'P3' in word ):
      if in_para == False:
         in_para = True
         para_type = word
      else:
         print 'Words in paragraph', para_type, ':', len(paragraph)
         print ' '.join(paragraph)
         del paragraph[:]
         para_type = word
  else:
    paragraph.append(word)
else:
  if in_para == True:
    print 'Words in last paragraph', para_type, ':', len(paragraph)
    print ' '.join(paragraph)
  else:
    print 'No words'