Count letter occurrences in a case insensitive sentence

Asked

Viewed 124 times

2

I wanted to be able to leave the variables of input as lower/upper to count equivalent letters in the sentence.

Only the variable is as iterable, and when I add the .lower() she changes to str and the code no longer works. I wanted help to do this another way.

Follows the code:

frase = input('Digite uma frase: ')
letra = input('Qual letra você deseja escanear? ')
c = 0
pos = []
for x in frase:
    if x == letra:
        c += 1
for n in enumerate(frase):
    if letra == n[1]:
        pos.append(n[0])
if c != 0:
    print(f'Existem {c} letra(s) "{letra}" na frase, nas posições {pos}.')
else:
    print(f'Não existe nenhum "{letra}" nesta frase.')
  • That’s what you’re trying to do? frase = input('Digite uma frase: ').upper() and letra = input('Qual letra você deseja escanear? ').upper()

2 answers

2

You can only use upper and lower in the comparison letter and use a single for to add the position and compare according to the following code:

frase = input('Digite uma frase: ')
letra = input('Qual letra você deseja escanear? ')
c = 0
pos = []

for x in range(len(frase)):
    if frase[x] == letra.lower() or frase[x] == letra.upper():
        pos.append(x+1)
        c += 1

if c != 0:
    print(f'Existem {c} letra(s) "{letra}" na frase, nas posições {pos}.')
else:
    print(f'Não existe nenhum "{letra}" nesta frase.')

By doing this you avoid modifying your "phrase" variable and prevent it from changing its type.

  • 1

    Valeuu. Very nice to see other views of the same thing.

2


I couldn’t understand what you meant by "when I add the .lower() she changes to str and the code no longer works", but anyway, if you want to capitalize everything (or everything in capital letters) in order to be able to make comparisons, one option would be to make input:

# transforma tudo em maiúscula
frase = input('Digite uma frase: ').upper()
letra = input('Qual letra você deseja escanear? ').upper()

# ou transforma tudo em minúscula
frase = input('Digite uma frase: ').lower()
letra = input('Qual letra você deseja escanear? ').lower()

Another detail is that you don’t have to do two loops. The enumerate already returns at the same time the position and the respective character, so just do:

c = 0
pos = []
for posicao, caractere in enumerate(frase):
    if letra == caractere:
        pos.append(posicao)
        c += 1

Or you can store only the list of positions, without needing the counter. If at the end of the for the list is empty, it is because it did not find anything:

pos = []
for posicao, caractere in enumerate(frase):
    if letra == caractere:
        pos.append(posicao)
if pos:
    print(f'Existem {len(pos)} letra(s) "{letra}" na frase, nas posições {pos}.')
else:
    print(f'Não existe nenhum "{letra}" nesta frase.')

The if pos: check if the list is not empty (here is used the fact that empty lists are considered False). Then, to know how many times the letter occurs, just get the list size with len.


You can still change the for above by a comprehensilist on, much more succinct and pythonic.:

pos = [ posicao for posicao, caractere in enumerate(frase) if letra == caractere ]

Of course you could also leave the sentence intact and only convert it to uppercase (or lowercase) when comparing the characters:

frase = input('Digite uma frase: ')
letra = input('Qual letra você deseja escanear? ').lower()

pos = [ posicao for posicao, caractere in enumerate(frase) if letra == caractere.lower() ]

Finally, if you really want to make a comparison case insensitive, can use the method casefold. It is similar to lower(), but a little more "aggressive" and treats special cases, as for example the character ß, which, when converted to capital, becomes "SS" (then 'ß'.upper().lower() returns "ss"):

print('ß'.lower() == 'SS'.lower()) # False
print('ß'.casefold() == 'SS'.casefold()) # True

Of course, for texts in Portuguese, it won’t make that much difference to use lower() or casefold(), but anyway, the tip is recorded.

  • Then, when executing the program, when I use . Lower() after the input, it stops recognizing the variable within the enumerate. It shows a message saying something like "expected to find iterable variable, but found str". And the code gives error. About not having to use the c, I had done this part first and I didn’t come back to adjust, but thanks, I’ll fix it. But anyway I would need to make a variable so I could give an option if there is no letter, it is not?

  • @punksn0g Did you test the codes I put above? I did it the way it is there and it did not give this error. Just to confirm, it is Python 3, right? I think in 2 o input behaves differently, see if it is running in the correct version

  • @punksn0g If there is no letter, it falls into the else and does not need this variable (if it falls in the else you know the letter occurs zero times, the counter is redundant)

  • I’ll try it here, Brigandan. Anything, I’ll comment again.

  • @punksn0g After testing, also remember that if one of the answers solved your problem, you can choose the one that best solved it and accept it, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem.

  • Joia, you can leave. I tried it here and it worked great. Very cool the use of the list comprehension, so that I love python, it’s all much simpler!

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.