2012-04-30 5 views
9

По состоянию на данный момент, у меня есть функция, чтобы заменить функцию countChars,программа Python, которая находит наиболее частое слово в текстовом файле, должны напечатать слово и его количество

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() 

ответ

14

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

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

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'] 

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

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) 
+0

Ничего себе. Хотя это, возможно, не тот метод, который мой профессор хочет, чтобы мы использовали, это отлично работает для нахождения числа. На этом этапе я бы предпочла их получить, чтобы они печатались в одном столбце для удобства чтения. Есть также несколько частей к заданию, которые включают: Просто распечатайте наиболее распространенное слово. Печать всех слов с их подсчетами в алфавитном порядке. И затем напечатайте все слова с их подсчетами в порядке частоты. Это довольно просто, если я не ошибаюсь, но я не знаю, совместимо ли то, что я узнал, с тем, что вы мне дали. – m96

+0

Задачи, которые вы упомянули, не очень сложны, вам нужно будет использовать '.sort()' или 'sorted()', возможно, искать, как сортировать словарь. Это ваша домашняя работа, и вам это нужно;), но если вы застряли в какой-то части, опубликуйте то, что у вас есть (как еще один вопрос), и кто-то поможет вам. – Akavall

17

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

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

words = re.compile(r"a-zA-Z'").findall(text) 
counts = collections.Counter(words) 

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

Счетчик действует почти так же, как словарь, но вы можете сделать что-то вроде 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 
+0

Yikes, я думал, что упомянул об этом в Python 2.7. – m96

+3

@ZachCorse Итак, ['collections.Counter'] (http://docs.python.org/library/collections.html#collections.Counter) –

+0

@ninjagecko Очевидно, вы знаете, что делаете, но это, кажется, впереди того, что я сейчас узнал. Я, наверное, глупый, но когда я пробую любую из этих вещей, точнее, самую первую, которую вы опубликовали, я получаю такую ​​ошибку. 'words = re.compile (r" a-zA-Z '"). Findall (текст) NameError: name' re 'не определен' – m96

3

У вас есть простая опечатка, words, где вы хотите word.

Редактировать: Вы, кажется, отредактировали источник. Пожалуйста, используйте копию и вставку, чтобы получить это в первый раз.

Редактировать 2: Видимо, вы не единственный, кто подвержен опечаткам. Реальная проблема в том, что у вас есть lines, где вы хотите line. Приношу извинения за то, что вы обвинили вас в редактировании источника.

+0

Не уверен, что вы имеете в виду. Я заменил функцию, которая ищет символы с тем, который ищет слова и заменяет одно слово в основной функции, чтобы оно выполнялось. – m96

+0

@ ZachCorse, я разобрался - см. Мое последнее редактирование. –

+0

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

1

Здесь возможное решение, не так элегантно, как 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 
+0

Возможно, вам стоит опубликовать образец вашего файла, чтобы мы могли видеть, как выглядит формат. – Akavall

+0

@ ZachCorse: вы можете найти http://www.ibm.com/developerworks/web/library/wa-debug/index.html, чтобы быть проницательным при изучении программирования. – ninjagecko

Смежные вопросы