Как посчитать количество слов в абзаце и исключить некоторые слова (из файла)? - PullRequest
3 голосов
/ 09 сентября 2011

Я только начал изучать Python, поэтому мой вопрос может быть немного глупым. Я пытаюсь создать программу, которая бы:
- импортировать текстовый файл (получил)
- подсчитать общее количество слов (получил его),
- подсчитать количество слов в определенном абзаце, начиная с определенной фразы (например, «P1», заканчивая другим участником «P2»), и исключить эти слова из моего количества слов. Каким-то образом я получил что-то, что подсчитывает количество символов вместо этого: /
- печатать абзацы отдельно (получил)
- исключить слова "P1", "P2" и т. Д. Из моего количества слов.

Мои текстовые файлы выглядят так:
P1: Бла бла бла.
P2: бла бла бла бла.
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 ]

2 голосов
/ 09 сентября 2011

Может быть, я не совсем понял требования, но я сделаю все возможное.

Первая часть о подсчете всех слов вполне подходит. Я бы немного его укоротил:

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 голосов
/ 09 сентября 2011

Первая часть в порядке, где вы получаете общее количество слов и распечатываете результат.

Здесь вы упали здесь

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 никогда не будет разбит на список слов.

Кроме того, условие else в цикле for всегда будет выполняться независимо от того, пуста последовательность или нет.Взгляните на 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'
2 голосов
/ 09 сентября 2011

Не следует звонить 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() 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...