Count number of times letters repeat in a text

1

Can you give me an idea how to write this algorithm in Python on less lines? (The algorithm counts the amount of a particular letter of the alphabet in a string.)

#INSERINDO TEXTO
string=input("Digite a string no qual quer ler quais letras do alfabetos elas possui:\t")

#DICIONARIO do alfabetos
alfabetos={'a':0, 'b':0, 'c':0, 'd':0, 'e':0, 'f':0, 'g':0, 'h':0, 'i':0, 'j':0, 'k':0, 'l':0, 'm':0, 'n':0,
'o':0, 'p':0, 'q':0, 'r':0, 's':0, 't':0, 'u':0, 'v':0, 'w':0, 'x':0, 'y':0, 'z':0}

#PERCORRENDO A STRING (caractere por caractere)
for b in string:
    if ((b=='a') or (b=='A')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='b') or (b=='B')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='c') or (b=='C')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='d') or (b=='D')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='e') or (b=='E')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='f') or (b=='F')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='g') or (b=='G')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='g') or (b=='G')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='h') or (b=='H')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='i') or (b=='I')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='j') or (b=='J')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='k') or (b=='K')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='l') or (b=='L')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='m') or (b=='M')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='n') or (b=='N')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='o') or (b=='O')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='p') or (b=='P')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='q') or (b=='Q')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='r') or (b=='R')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='s') or (b=='S')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='t') or (b=='T')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='u') or (b=='U')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='v') or (b=='V')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='w') or (b=='W')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='x') or (b=='X')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='y') or (b=='Y')):
        alfabetos[b]=alfabetos[b]+1
    elif ((b=='z') or (b=='Z')):
        alfabetos[b]=alfabetos[b]+1

#VARIAVEL QUE CONTEM A CHAVES E CONTEUDO DO DICIONARIO
lista=list(alfabetos.items())

#PRINTANDO
print(lista)
    
asked by anonymous 12.07.2018 / 22:27

2 answers

3

Yes, just use collections.Counter , which already does it for you :

from collections import Counter

texto = 'Stack Overflow em Português'
counter = Counter(texto)

print(counter)

The output is:

Counter({' ': 3, 't': 2, 'e': 2, 'r': 2, 'o': 2, 'u': 2, 'S': 1, 'a': 1, 'c': 1, 'k': 1, 'O': 1, 'v': 1, 'f': 1, 'l': 1, 'w': 1, 'm': 1, 'P': 1, 'g': 1, 'ê': 1, 's': 1})

In this case, it will consider all the characters in the text, including space and differentiating accented letters, e of ê , for example, and lowercase letters, but you can start playing.

    
12.07.2018 / 22:36
2

The most direct and advisable way is to use what already exists, Counter , as @ AndersonCarlosWoss has already indicated.

However picking up on your algorithm, you can manually do what you want without too many changes. Before I start it does not work for uppercase letters even though they are included in ifs because the dictionary does not initially have the uppercase keys and gives an error when it tries to access them.

If you want to save both versions (uppercase / lowercase) as lowercase, then just convert the entire sentence to lowercase with lower() before you go:

for b in string.lower():

You also do not need to create keys initially, you can create them as they pop up in the sentence:

#DICIONARIO do alfabetos
alfabetos = {}

#PERCORRENDO A STRING (caractere por caractere)
for b in string.lower():
    alfabetos[b] = alfabetos[b] + 1 if b in alfabetos else 1

Now in each passing letter, if you do not already have alfabetos saved with count 1 if you already have guard with the count that is 1 .

From here to only interpret a-z just another if :

#DICIONARIO do alfabetos
alfabetos = {}

#PERCORRENDO A STRING (caractere por caractere)
for letra in string.lower():
    if 'a' <= letra <= 'z':  # só se for letra
        alfabetos[letra] = alfabetos[letra] + 1 if letra in alfabetos else 1

To count numbers you can use defaultdict(int) which is a subclass of dict that makes it easy, since whenever it has no value it will consider 0 and therefore avoid existence test:

from collections import defaultdict
#DICIONARIO do alfabetos
alfabetos = defaultdict(int)

#PERCORRENDO A STRING (caractere por caractere)
for letra in string.lower():
    if 'a' <= letra <= 'z':
        alfabetos[letra] += 1  # agora basta somar

Note that this last change meant adding another import

    
12.07.2018 / 22:57