Incorrect operation of a character counter within strings in Python

1

Suppose I have the following sentence:

oracion = 'Mi perro bonito come todas las noches'

And I want to create a function that tells the occurrence of each character within it. To that end, we import string and create an alphabet that is our reference:

import string

alphabet = string.ascii_letters

The function I did for the word counter is:

def contador(str):
    count= {}
    for letter in str:
        if letter in alphabet:
            if letter in count.keys():
                count[letter]+=1
        else:
                count[letter]=1
    return count

When I run

contador(oracion)

I always get this exit:

Out[1]: {' ': 1}

That is, there is no dictionary that registers the frequency of each letter within the sentence. Could you tell me what the source of the error is? Honestly my knowledge has not given me yet to find out what I'm wrong about, since I think the reasoning behind the function is correct. Thanks in advance.

    
asked by Alejandro Carrera 12.10.2017 в 07:21
source

2 answers

0

The error is in the level of indentation of the else. Antonio's response is corrected but the cause is not explained. It must always be remembered that the blocks of code in Python are defined by the levels of indentation. As the code is, the logic is as follows:

  • If the letter is in alphabet it is checked if it is already in the dictionary. If it is, one is added to the value. If the key is not in the dictionary, nothing is done.

  • If the letter is not in alphabet the else is used and the key is added to the dictionary. This causes that only the characters not present in alphabet are not added to the dictionary, in this case the space.

  • An indentation level must be added to else so that it is at the same level of if letter in count.keys(): , so that if this is not fulfilled, its content is executed and the key is added.

    import string
    alphabet = string.ascii_letters
    
    def contador(str_):
        count= {}
        for letter in str_:
            if letter in alphabet:
                if letter in count.keys():
                   count[letter] += 1
    
           #else  <<< A este nivel está en tu código, y debe ser:
                else:
                    count[letter] = 1
    
        return count
    

    Keep in mind that does not include capital letters, "ñ", accented vowels or "ü" .

    On the other hand, to count appearances in an iterable collections.Counter offers a simple and much more efficient solution. This returns us a dictionary counting all the characters (not just letters), we can filter it if we want it without problems:

    from collections import  Counter
    import string
    
    alphabet = set(string.ascii_letters + ("áéíóúÁÉÍÓÚñÑÜü"))
    def contador(str_):
        count = Counter(oracion)
        return {key: count[key] for key in alphabet & count.keys()}
    
    oracion = 'Cigüeña, camión, 123'
    print(contador(oracion))
    

    Exit:

    {'n': 1, 'i': 2, 'C': 1, 'a': 2, 'c': 1, 'e': 1, 'm': 1, 'ó': 1, 'ü': 1, 'y': 1, 'g': 1, 'ñ': 1}
    

    It differs between uppercase and lowercase. If you want to count both cases in one, it is not possible either.

        
    answered by 12.10.2017 / 12:21
    source
    0

    Good morning: Your script is almost correct because it worked for me. I write you here:     import string     alphabet = string.ascii_letters

    oracion = 'Mi perro bonito come todas las noches'
    
    def contador(str):
        count= {}
        for letter in str:
            if letter in alphabet:
                if letter in count.keys():
                    count[letter]+=1
                else:
                    count[letter]=1
        return count
    
    print(contador(oracion))
    

    That's how it worked for me. He has shown me on the screen an associative array of letters and their repetitions.

    You needed to use the print () function . I tested it in an editor that I have on my mobile and it worked correctly

        
    answered by 12.10.2017 в 08:38