2013-09-05 3 views
4

Я начинающий программист на языке python, и я пытаюсь создать программу, которая подсчитывает количество букв в текстовом файле. Вот что у меня до сих пор:Подсчитайте буквы в текстовом файле

import string 
text = open('text.txt') 
letters = string.ascii_lowercase 
for i in text: 
    text_lower = i.lower() 
    text_nospace = text_lower.replace(" ", "") 
    text_nopunctuation = text_nospace.strip(string.punctuation) 
    for a in letters: 
    if a in text_nopunctuation: 
     num = text_nopunctuation.count(a) 
     print(a, num) 

Если текстовый файл содержит hello bob, я хочу выход быть:

b 2 
e 1 
h 1 
l 2 
o 2 

Моя проблема заключается в том, что она не работает должным образом, когда текстовый файл содержит более одной строки текста или имеет знаки препинания.

ответ

1

Вы должны использовать collections.Counter

from collections import Counter 
text = 'aaaaabbbbbccccc' 
c = Counter(text) 
print c 

Он печатает:

Counter({'a': 5, 'c': 5, 'b': 5}) 

Ваш text переменная должна быть:

import string 
text = open('text.txt').read() 
# Filter all characters that are not letters. 
text = filter(lambda x: x in string.letters, text.lower()) 

Для получения выходного сигнала вам необходимо:

for letter, repetitions in c.iteritems(): 
    print letter, repetitions 

В моем примере он печатает:

a 5 
c 5 
b 5 

Для получения дополнительной информации Counters doc

10

Это очень читаемый способ сделать то, что вы хотите с помощью Counter:

from string import ascii_lowercase 
from collections import Counter 

with open('text.txt') as f: 
    print Counter(letter for line in f 
        for letter in line.lower() 
        if letter in ascii_lowercase) 

Вы можете перебирать в результате dict, чтобы напечатать его в том формате, который вы хотите.

+0

Вы просто не хватает 'line.lower()'. –

+0

Вы правильно благодарите, исправили его. – elyase

1

Использование повторно:

import re 

context, m = 'some file to search or text', {} 
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] 
for i in range(len(letters)): 
    m[letters[i]] = len(re.findall('{0}'.format(letters[i]), context)) 
    print '{0} -> {1}'.format(letters[i], m[letters[i]]) 

Это гораздо более элегантный и чистый со счетчиком, тем не менее.

+0

Это работает хорошо для меня, но я не могу заставить его правильно открыть текстовый файл. Я попытался заменить бит «некоторый файл на поиск или текст» открытым («text.txt»), но он не работал. Я продолжаю получать больше, чем один, чтобы распаковать ошибку. Также я не понимаю, что вы делаете в контексте переменных и m. Не могли бы вы мне помочь? – user2752551

+1

Обязательно. Просто используйте: с открытым ('file.txt', 'r') в качестве файла: context = file.read() Вы, вероятно, столкнулись с известным итератором производительности python. –

1
import string 
fp=open('text.txt','r') 
file_list=fp.readlines() 
print file_list 
freqs = {} 
for line in file_list: 
    line = filter(lambda x: x in string.letters, line.lower()) 
    for char in line: 
     if char in freqs: 
      freqs[char] += 1 
     else: 
      freqs[char] = 1 

print freqs 
0

Просто для полноты картины, если вы хотите сделать это без использования Counter, вот еще один очень короткий путь, используя список понимание и dict встроенной команды:

from string import ascii_lowercase as letters 
with open("text.txt") as f: 
    text = f.read().lower() 
    print dict((l, text.count(l)) for l in letters) 

f.read() будет считывать содержимое всего файла в переменную text (может быть, плохая идея, если файл действительно большой); то мы используем понимание списка для создания списка кортежей (letter, count in text) и конвертируем этот список кортежей в словарь. С Python 2.7+ вы также можете использовать {l: text.count(l) for l in letters}, который еще короче и немного читабельнее.

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

0

Вы могли бы разделить задачу на две более простые задачи:

#!/usr/bin/env python 
import fileinput # accept input from stdin and/or files specified at command-line 
from collections import Counter 
from itertools import chain 
from string import ascii_lowercase 

# 1. count frequencies of all characters (bytes on Python 2) 
freq = Counter(chain.from_iterable(fileinput.input())) # read one line at a time 

# 2. print frequencies of ascii letters 
for c in ascii_lowercase: 
    n = freq[c] + freq[c.upper()] # merge lower- and upper-case occurrences 
    if n != 0: 
     print(c, n) 
Смежные вопросы