2014-09-16 4 views
0

Мне нужно запомнить количество слов для каждого слова в нескольких файлах. В Perl я использовал хэш хэша, например $wcCount{$file}{$word}. Я не могу понять, как сделать подобное в python. Я пытался использовать что-то из этого эффекта, но это явно не работаетЗаполнение словаря в python

for line in fh: 
    arr = line.split() 
    for word in arr: 
     key = filename + word #creates a unique identifier for each word count 
     freqdict[key] += 1 

Я прочитал другой StackOverflow за аналогичный вопрос, однако он не позволяет обновлять значение, как слово снова подсчитывали.

Ввод - это несколько файлов, заполненных словами. Вывод должен быть просто списком частот для слова (которое помещается как аргумент командной строки) для каждого файла.

+0

Не могли бы вы представить пример ввода и ожидаемого выхода? –

+0

ах, я добавлю, спасибо. – Achaldo

ответ

0

Я хотел бы предложить collections.Counter, если вы в Python 2.7 или более поздней версии:

import collections 

counter = collections.Counter() 

for line in fh: 
    arr = line.split() 
    for word in arr: 
     key = filename + word #creates a unique identifier for each word count 
     counter.update((key,)) 

Вы можете просмотреть счетчики, как это:

for key, value in counter.items(): 
    print('{0}: {1}'.format(key, value)) 
+0

Почему бы вам объединить имя файла и слово вместо использования указателя счетчиков с именами файлов в виде ключей dict? – DaoWen

+0

Потому что это не спецификация. –

1

Вы, вероятно, может уйти с использованием Counter и используя кортеж (имя файла, слово) в качестве ключевого значения, например:

from collections import Counter 
from itertools import chain 

word_counts = Counter() 
for filename in ['your', 'file names', 'here']: 
    with open(filename) as fin: 
     words = chain.from_iterable(line.split() for line in fin) 
     word_counts.update((filename, word) for word in words) 

Ho wever, то, что вы могли бы также сделать, - создать начальный словарь на основе имен файлов с Counter, а затем обновить его, чтобы у вас был доступ к «хэшу» как бы с именем файла в качестве ключа, а затем подсчет слов, например :

word_counts = {filename: Counter() for filename in your_filenames} 
for filename, counter in word_counts.items(): 
    with open(filename) as fin: 
     words = chain.from_iterable(line.split() for line in fin) 
     word_counts[filename].update(words) 
0

Я не программист Perl, но я считаю, что следующее решение в Python будет получить вам ближе всего к $wcCount{$file}{$word} в Perl.

from collections import Counter 
from itertools import chain 

def count_words(filename): 
    with open(filename, 'r') as f: 
     word_iter = chain.from_iterable(line.split() for line in f) 
     return Counter(word_iter) 

word_counts = {file_name : count_words(file_name) for file_name in file_names} 
2

Предположим, у вас есть Hamlet, и вы хотите посчитать уникальные слова.

Вы можете сделать:

# the tools we need, read a url and regex library 
import urllib2 
import re 

# a dict -- similar to Perl hash 
words={} 

# read the text at that url 
response = urllib2.urlopen('http://pastebin.com/raw.php?i=7p3uycAz') 
hamlet = response.read() 

# split on whitespace, remove trailing punctuation, and count each unique word 
for word in hamlet.split(): 
    word=re.sub(r'\W+$', r'', word) 
    if word.strip(): 
     words[word]=words.setdefault(word, 0) +1 

Затем, если вы хотите напечатать слова, отсортированные от наиболее распространенной в меньшей мере:

# sort descending on count, ascending on ascii lower case 
for word, count in sorted(words.items(), key=lambda t: (-t[1], t[0].lower())): 
    print word, count 

Печать:

the 988 
and 702 
of 628 
to 610 
I 541 
you 495 
a 452 
my 441 
in 399 
HAMLET 385 
it 360 
is 313 
... 

Если вы хотите вложенный Dict of Dicts (как показывает пример на Perl), вы можете сделать что-то вроде этого:

# think of these strings like files; the letters like words 
str1='abcdefaaa' 
str2='abefdd' 
str3='defeee' 

letters={} 

for fn, st in (('string 1', str1), ('string 2', str2) , ('string 3', str3)): 
    letters[fn]={} 
    for c in st: 
     letters[fn][c]=letters[fn].setdefault(c, 0) 
     letters[fn][c]+=1 

print letters  
# {'string 3': {'e': 4, 'd': 1, 'f': 1}, 
    'string 1': {'a': 4, 'c': 1, 'b': 1, 'e': 1, 'd': 1, 'f': 1}, 
    'string 2': {'a': 1, 'b': 1, 'e': 1, 'd': 2, 'f': 1}} 
0

Или вы можете узнать об nltk (Набор инструментов для естественного языка). Если вы в конечном итоге делаете больше, чем просто частоту слов, это может быть большой помощью.

Здесь он разбирает из предложений, а затем слова:

import nltk 
import urllib2 

hamlet = urllib2.urlopen('http://pastebin.com/raw.php?i=7p3uycAz').read().lower() 

word_freq = nltk.FreqDist() 
for sentence in nltk.sent_tokenize(hamlet): 
    for word in nltk.word_tokenize(sentence): 
     word_freq[word] += 1 

word_freq:

FreqDist ({», ': 3269,'.': 1283,': 1138, 'и': 965, 'to': 737, 'of:: 669,' i ': 629,'; ': 582,' you ': 553,': ': 535, ...})