3

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

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

我最终得到了这段代码:

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'

任何想法如何改进它?

谢谢

4

3 回答 3

2

您不应该open ('zery.txt', 'r')使用标识符text调用。它不是文件中的文本,而是文件的处理程序,在文档中被描述为“类文件对象”(顺便说一句,我从来不明白它的含义,“类文件对象”)

.

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.

thenwords_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() 
于 2011-09-09T10:53:03.263 回答
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 时,不会调用拆分方法并words_par保持为字符串(而不是预期的字符串列表)。所以len(words_par)返回字符数而不是单词数。

(在名称上有点离题:恕我直言,这个错误是由于变量命名不准确引起的。不同的命名

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

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

于 2011-09-09T10:54:48.203 回答
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'
于 2011-09-09T13:55:19.040 回答