Вопрос по python – Программа на Python, которая находит наиболее часто встречающееся слово в текстовом файле, должна печатать слово и его количество

12

На данный момент у меня есть функция, чтобы заменить функцию countChars,

def countWords(lines):
  wordDict = {}
  for line in lines:
    wordList = lines.split()
    for word in wordList:
      if word in wordDict: wordDict[word] += 1
      else: wordDict[word] = 1
  return wordDict

но когда я запускаю программу, она выплевывает эту мерзость (это всего лишь пример, около двух страниц слов с огромным числом рядом с ней)

before 1478
battle-field 1478
as 1478
any 1478
altogether 1478
all 1478
ago 1478
advanced. 1478
add 1478
above 1478

Хотя очевидно, что это означает, что код достаточно надежен для запуска, я не получаю из него того, что хочу. Необходимо указать, сколько раз каждое слово содержится в файле (gb.txt, который является адресом Геттисберга). Очевидно, что каждое слово, которое находится в файле, не находится там ровно 1478 раз.

Я довольно новичок в программировании, поэтому я немного озадачен ...

from __future__ import division

inputFileName = 'gb.txt'

def readfile(fname):
  f = open(fname, 'r')
  s = f.read()
  f.close()
 return s.lower()

def countChars(t):
  charDict = {}
  for char in t:
    if char in charDict: charDict[char] += 1
    else: charDict[char] = 1
  return charDict

def findMostCommon(charDict):
  mostFreq = ''
  mostFreqCount = 0
  for k in charDict:
    if charDict[k] > mostFreqCount:
      mostFreqCount = charDict[k]
      mostFreq = k
  return mostFreq

def printCounts(charDict):
  for k in charDict:
    #First, handle some chars that don't show up very well when they print
    if k == '\n': print '\\n', charDict[k]  #newline
    elif k == ' ': print 'space', charDict[k]
    elif k == '\t': print '\\t', charDict[k] #tab
    else: print k, charDict[k]  #Normal character - print it with its count

def printAlphabetically(charDict):
  keyList = charDict.keys()
  keyList.sort()
  for k in keyList:
    #First, handle some chars that don't show up very well when they print
    if k == '\n': print '\\n', charDict[k]  #newline
    elif k == ' ': print 'space', charDict[k]
    elif k == '\t': print '\\t', charDict[k] #tab
    else: print k, charDict[k]  #Normal character - print it with its count

def printByFreq(charDict):
  aList = []
  for k in charDict:
    aList.append([charDict[k], k])
  aList.sort()     #Sort into ascending order
  aList.reverse()  #Put in descending order
  for item in aList:
    #First, handle some chars that don't show up very well when they print
    if item[1] == '\n': print '\\n', item[0]  #newline
    elif item[1] == ' ': print 'space', item[0]
    elif item[1] == '\t': print '\\t', item[0] #tab
    else: print item[1], item[0]  #Normal character - print it with its count

def main():
  text = readfile(inputFileName)
  charCounts = countChars(text)
  mostCommon = findMostCommon(charCounts)
  #print mostCommon + ':', charCounts[mostCommon]
  #printCounts(charCounts)
  #printAlphabetically(charCounts)
  printByFreq(charCounts)

main()

Ваш Ответ

5   ответов
2
 words = ['red', 'green', 'black', 'pink', 'black', 'white', 'black', 
'eyes','white', 'black', 'orange', 'pink', 'pink', 'red', 'red', 
'white', 'orange', 'white', "black", 'pink', 'green', 'green', 'pink', 
'green', 'pink','white', 'orange', "orange", 'red']

 from collections import Counter
 counts = Counter(words)
 top_four = counts.most_common(4)
 print(top_four)
20

Если вам нужно посчитать количество слов в отрывке, то лучше использовать регулярное выражение.

Давайте начнем с простого примера:

import re

my_string = "Wow! Is this true? Really!?!? This is crazy!"

words = re.findall(r'\w+', my_string) #This finds words in the document

Результат:

>>> words
['Wow', 'Is', 'this', 'true', 'Really', 'This', 'is', 'crazy']

Обратите внимание, что & quot; Is & quot; и "is" два разных слова. Я предполагаю, что вы хотите, чтобы они считали их одинаково, поэтому мы можем просто использовать все слова с заглавной буквы, а затем считать их.

from collections import Counter

cap_words = [word.upper() for word in words] #capitalizes all the words

word_counts = Counter(cap_words) #counts the number each time a word appears

Результат:

>>> word_counts
Counter({'THIS': 2, 'IS': 2, 'CRAZY': 1, 'WOW': 1, 'TRUE': 1, 'REALLY': 1})

Тебе здесь хорошо?

Теперь нам нужно сделать то же самое, что мы делали выше, только в этот раз, когда мы читаем файл.

import re
from collections import Counter

with open('your_file.txt') as f:
    passage = f.read()

words = re.findall(r'\w+', passage)

cap_words = [word.upper() for word in words]

word_counts = Counter(cap_words)
Задачи, которые вы упоминаете, не очень сложны, вам нужно использовать.sort() или жеsorted(), может быть, искать, как отсортировать словарь. Это ваша домашняя работа, и она для вас;), но если вы застряли в какой-то части, напишите, что у вас есть (в качестве другого вопроса), и кто-то поможет вам.
Вот это да. Хотя это может быть и не тот метод, который хочет использовать мой профессор, он идеально подходит для определения числа. На этом этапе мне желательно получить их, чтобы они печатались в одном столбце для удобства чтения. В задании также есть несколько частей, которые включают в себя: Просто печатать наиболее распространенное слово. Печать всех слов с их счетами в алфавитном порядке. А затем распечатать все слова с их счетами в порядке частоты. Это довольно просто, если я не ошибаюсь, но я не знаю, совместимо ли то, что я узнал, с тем, что вы мне дали до сих пор. m96
Могу ли я добавить, что можноpassage = f.read().upper() в одну строку
17

Эта программа на самом деле является 4-х линейной, если вы используете мощные инструменты в вашем распоряжении:

with open(yourfile) as f:
    text = f.read()

words = re.compile(r"[\w']+", re.U).findall(text)   # re.U == re.UNICODE
counts = collections.Counter(words)

Регулярное выражение найдет все слова, независимо от примыкающей к ним пунктуации (но считая апострофы как часть слова).

Счетчик действует почти как словарь, но вы можете делать такие вещи, какcounts.most_common(10)и добавьте количество и т. д.help(Counter)

Я бы также предложил, чтобы вы не делали функцииprintBy..., поскольку только функции без побочных эффектов легко использовать повторно.

def countsSortedAlphabetically(counter, **kw):
    return sorted(counter.items(), **kw)

#def countsSortedNumerically(counter, **kw):
#    return sorted(counter.items(), key=lambda x:x[1], **kw)
#### use counter.most_common(n) instead

# `from pprint import pprint as pp` is also useful
def printByLine(tuples):
    print( '\n'.join(' '.join(map(str,t)) for t in tuples) )

Демо-версия:

>>> words = Counter(['test','is','a','test'])
>>> printByLine( countsSortedAlphabetically(words, reverse=True) )
test 2
is 1
a 1

edit to address Mateusz Konieczny's comment: replaced [a-zA-Z'] with [\w']... the character class \w, according to the python docs, "Matches Unicode word characters; this includes most characters that can be part of a word in any language, as well as numbers and the underscore. If the ASCII flag is used, only [a-zA-Z0-9_] is matched." (... but apparently doesn't match an apostrophe...) However \w includes _ and 0-9, so if you don't want those and you aren't working with unicode, you can use [a-zA-Z']; if you are working with unicode you'd need to do a negative assertion or something to subtract [0-9_] from the \w character class

Попробуйте начать сimport re. import collections может помочь тоже.
@ZachCorse Так и естьcollections.Counter
words = re.compile(r"a-zA-Z'").findall(text) не используется для неязыкового текста (например, для польских слов -text="Zażółć gęślą jaźń")
@ninjagecko Ясно, что вы знаете, что делаете, но это, кажется, опережает то, что я изучил в настоящее время. Возможно, это прозвучит глупо, но когда я попробую что-нибудь из этого, а точнее самое первое, что вы опубликовали, я получу ошибку имени, подобную этой.words = re.compile(r"a-zA-Z'").findall(text) NameError: name 're' is not defined m96
Да, я думал, я упоминал, что это было в Python 2.7. m96
2

Здесь возможное решение, не такое элегантное, как у ninjagecko, но все же:

from collections import defaultdict

dicto = defaultdict(int)

with open('yourfile.txt') as f:
    for line in f:
        s_line = line.rstrip().split(',') #assuming ',' is the delimiter
        for ele in s_line:
            dicto[ele] += 1

 #dicto contians words as keys, word counts as values

 for k,v in dicto.iteritems():
     print k,v
@ZachCorse: вы можете найтиibm.com/developerworks/web/library/wa-debug/index.html быть проницательным при изучении программирования.
Возможно, вам следует опубликовать образец вашего файла, чтобы мы могли посмотреть, как выглядит формат.
3

You have a simple typo, words where you want word.

Edit: You appear to have edited the source. Please use copy and paste to get it right the first time.

Edit 2: Очевидно, вы не единственный, кто склонен к опечаткам. Настоящая проблема в том, что у вас естьlines где вы хотитеline, Я прошу прощения за обвинение вас в редактировании источника.

Когда я удаляю s из строк, он только учитывает символы. РЕДАКТИРОВАТЬ: Ой, нажмите ввод слишком быстро. Мне нужно, чтобы посчитать, сколько каждого слова есть в файле. Когда строчные буквы присоединены к строкам, он смотрит на количество слов, но не считает их. (есть цифры, но почему-то они в основном все одинаковые) m96
Не уверены, что вы имеете в виду. Я заменил функцию, которая ищет символы, на функцию, которая ищет слова, и заменил одно слово в основной функции, чтобы оно выполнялось. m96
@ ZachCorse, я облажался - см. Мое последнее изменение.

Похожие вопросы