2008-10-23 32 views
40

Como ejemplo, digamos que quería enumerar la frecuencia de cada letra del alfabeto en una cadena. ¿Cuál sería la forma más fácil de hacerlo?¿Cómo puedo iterar a través de una cadena en Python?

Este es un ejemplo de lo que estoy pensando ... la pregunta es cómo hacer que allTheLetters sea igual a dichas letras sin algo así como allTheLetters = "abcdefg ... xyz". En muchos otros idiomas, podría escribir letras ++ e ir más allá del alfabeto, pero hasta ahora no he encontrado una manera de hacerlo en Python.

def alphCount(text): 
    lowerText = text.lower() 
    for letter in allTheLetters: 
    print letter + ":", lowertext.count(letter) 

Respuesta

72

La pregunta lo solicitado (la manera de recorrer el alfabeto) no es la misma pregunta que el problema que estamos tratando de resolver (cómo contar la frecuencia de las letras de una cadena).

Usted puede utilizar string.lowercase, como otros críticos han sugerido:

import string 
allTheLetters = string.lowercase 

Para hacer las cosas de la forma en que está "acostumbrado a", el tratamiento de las letras como números, se puede utilizar el "ord" y funciones "chr".No hay absolutamente ninguna razón para nunca hacer exactamente esto, pero tal vez se acerca más a lo que en realidad está tratando de averiguar:

def getAllTheLetters(begin='a', end='z'): 
    beginNum = ord(begin) 
    endNum = ord(end) 
    for number in xrange(beginNum, endNum+1): 
     yield chr(number) 

Se puede decir que hace lo correcto, porque este código imprime True:

import string 
print ''.join(getAllTheLetters()) == string.lowercase 

Pero, para resolver el problema en realidad se está tratando de resolver, que desea usar un diccionario y recoger las cartas sobre la marcha:

from collections import defaultdict  
def letterOccurrances(string): 
    frequencies = defaultdict(lambda: 0) 
    for character in string: 
     frequencies[character.lower()] += 1 
    return frequencies 

uso de este modo:

occs = letterOccurrances("Hello, world!") 
print occs['l'] 
print occs['h'] 

Esto imprimirá '3' y '1' respectivamente.

Tenga en cuenta que esto funciona para Unicode, así:

# -*- coding: utf-8 -*- 
occs = letterOccurrances(u"héĺĺó, ẃóŕĺd!") 
print occs[u'l'] 
print occs[u'ĺ'] 

Si se va a probar el otro enfoque en Unicode (incrementando a través de cada personaje) que estaría esperando mucho tiempo; hay millones de caracteres Unicode.

para implementar su función original (imprimir los cargos de cada letra en orden alfabético) en cuanto a esto:

def alphCount(text): 
    for character, count in sorted(letterOccurrances(text).iteritems()): 
     print "%s: %s" % (character, count) 

alphCount("hello, world!") 
+1

Excelente tutorial! – Ber

+3

realmente debería usar string.ascii_lowercase en lugar de escribir su propia getAllTheLetters. ¡también, ese es un nombre terriblemente antipático para una función! – hop

+0

Su función letterOccurrances() también contará el espacio en blanco y la puntuación, tal vez no intencionalmente. – mhawke

3

¿Alló como esto?

for letter in range(ord('a'), ord('z') + 1): 
    print chr(letter) + ":", lowertext.count(chr(letter)) 

(no hablo de Python; Por favor, perdona mis errores de sintaxis)

+0

creo que su "carta" dentro de la cuenta() debería ser "chr (carta)" – paxdiablo

+0

Desde que lo arregló (y no tenía mi error de "uno por uno", lo que resulta en solo comprobar hasta 'y' :-), he borrado mi respuesta y he votado por encima del suyo. – paxdiablo

+2

Esto se ve bien para mí, ¿por qué está siendo rechazado? –

14

la pregunta es cómo hacer allTheLetters igual a dicho letras sin algo así como allTheLetters = "abcdefg .. .xyz"

que en realidad es proporcionada por el módulo string, que no es como usted tiene que escribir manualmente usted mismo;)

import string 

allTheLetters = string.ascii_lowercase 

def alphCount(text): 
    lowerText = text.lower() 
    for letter in allTheLetters: 
    print letter + ":", lowertext.count(letter) 
+0

Esta solución es lenta, ya que tiene iteraciones anidadas (lowertext.count() itera sobre la cadena para encontrar el conteo) – Ber

+4

Sin embargo, la pregunta específica fue respondida. Otros problemas son los problemas con los carteles originales. – paxdiablo

+0

o puede obtener todas las letras minúsculas haciendo una iteración en la siguiente lista: allTheLetters = [chr (i + 97) para i en el rango (26)] –

3

Qué quiere decir usando:

import string 
string.ascii_lowercase 

entonces,

counters = dict() 
for letter in string.ascii_lowercase: 
    counters[letter] = lowertext.count(letter) 

Todas las letras minúsculas se contabilizan, contadores faltante tendrá valor cero.

utilizando generadores:

counters = 
    dict((letter,lowertext.count(letter)) for letter in string.ascii_lowercase) 
9

Si lo que desea es hacer un recuento de la frecuencia de una cadena, intente esto:

s = 'hi there' 
f = {} 

for c in s: 
     f[c] = f.get(c, 0) + 1 

print f 
+0

Esta es una solución muy simple ya que solo itera una vez sobre el cadena, y por lo tanto es O (n) en lugar de usar iteraciones anidadas. evento mejor si usa f = defaultdict (int) y simplemente f [c] + = 1 – Ber

+0

¿Es el miembro get O (1)? Si es O (n), entonces todo es O (n^2). – paxdiablo

+0

@Pax Diablo: las asignaciones son hash. El diccionario obtiene O (1). –

2

pregunta principal es "iterar a través del alfabeto":

import string 
for c in string.lowercase: 
    print c 

Cómo obtener frecuencias de letras con cierta eficiencia y sin contar caracteres que no sean letras:

import string 

sample = "Hello there, this is a test!" 
letter_freq = dict((c,0) for c in string.lowercase) 

for c in [c for c in sample.lower() if c.isalpha()]: 
    letter_freq[c] += 1 

print letter_freq 
4

Para contar objetos, la solución obviaes la Counter

from collections import Counter 
import string 

c = Counter() 
for letter in text.lower(): 
    c[letter] += 1 

for letter in string.lowercase: 
    print("%s: %d" % (letter, c[letter])) 
+4

Aún más fácil, puede reemplazar el bucle de asignación con: 'c = Counter (text.lower())' –

-1

Esto es lo que hago:

import string 
for x in list(string.lowercase): 
    print x 
0

Cómo sobre esto, utilizar letras, cifras y puntuacion (todos utilizables para formar una clave de Django):

import random 
import string 

chars = string.letters + string.digits + string.punctuation 
chars_len = len(chars) 
n = 40 

print(''.join([chars[random.randint(0, chars_len)] for i in range(n)])) 

Ejemplo resultado: cool:! V D + P, & S * hzbO {a0_6] 2 { 4 | OIbVuAbq0:

0

sólo tiene que utilizar:

import string 
string.lowercase 
string.uppercase 

o

string.letters[:26] 
string.letters[26:] 
Cuestiones relacionadas