Contar letras en un archivo de texto.

Soy un progtwigdor principiante de Python y estoy tratando de hacer un progtwig que cuente el número de letras en un archivo de texto. Esto es lo que tengo hasta ahora:

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) 

Si el archivo de texto contiene hello bob , quiero que la salida sea:

 b 2 e 1 h 1 l 2 o 2 

Mi problema es que no funciona correctamente cuando el archivo de texto contiene más de una línea de texto o tiene puntuación.

Esta es una forma muy legible de lograr lo que quiere usando 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) 

Puede repetir el dictamen resultante para imprimirlo en el formato que desee.

Tienes que usar las collections.Counter

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

Se imprime:

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

Su variable de text debe ser:

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

Para obtener la salida que necesita:

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

En mi ejemplo se imprime:

 a 5 c 5 b 5 

Para más información contadores doc.

Utilizando re:

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

Es mucho más elegante y limpio con Contador sin embargo.

 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 

Solo por el bien de la integridad, si desea hacerlo sin usar Counter , aquí hay otra forma muy breve, usando la comprensión de lista y el dict incorporado:

 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() leerá el contenido de todo el archivo en la variable de text (podría ser una mala idea, si el archivo es realmente grande); luego usamos una lista de comprensión para crear una lista de tuplas (letter, count in text) y convertir esta lista de tuplas a un diccionario. Con Python 2.7+ también puedes usar {l: text.count(l) for l in letters} , que es aún más corto y un poco más legible.

Sin embargo, tenga en cuenta que esto buscará el texto varias veces, una por cada letra, mientras que Counter escanea solo una vez y actualiza los conteos de todas las letras de una sola vez.

Podría dividir el problema en dos tareas más simples:

 #!/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)