Me ajudem com um código de python

f = str(input(‘Digite uma frase:’)).lower().strip()
vez = f.count(‘a’)
pri = f.find(‘a’) + 1
ult = f.rfind(‘a’) + 1
print(f’’‘A letra A aparece {vez} vezes na frase,
Aparece pela primeira vez na posição {pri}
E aparece pela última vez na posição {ult}’’’)

NESSE CÓDIGO, SE A PESSOA COLOCAR UM ‘‘A’’ SÓ QUE COM ACENTO, O CÓDIGO NÃO CONTA, PRECISO COLOCAR MANUALMENTE TODOS OS ACENTOS OU HÁ ALGUMA FUNÇÃO QUE FAÇA ISSO ?

O a e o á de fato são considerados caracteres diferentes. Assim como o â, ã e à. Por isso que se chamar count com um, ele não conta o outro.

Você até poderia fazer um count (e um find e rfind) pra cada um deles, mas na boa, isso é bem ineficiente, já que cada chamada de count percorre toda a string para fazer a contagem, e o mesmo vale para find e rfind, que no pior caso - quando a letra não existe - também percorre toda a string (mesmo no melhor caso, quando a letra existe, ainda sim você terá que verificar qual deles ocorre primeiro para saber qual é a primeira posição, por exemplo - uma complicação desnecessária).

Em vez disso, dá pra fazer em um único loop:

frase = input('Digite uma frase').lower().strip()
cont = 0
letras = ('a', 'á', 'â', 'ã', 'à') # todas as letras que quero procurar
for posicao, caractere in enumerate(frase):
    if caractere in letras:
        cont += 1
        if cont == 1: # se é a primeira ocorrência
            inicio = posicao
        fim = posicao

if cont == 0:
    print(f'Não foi encontrada nenhuma ocorrência')
else:
    print(f'Foram encontradas {cont} ocorrências, a primeira na posição {inicio} e a última na posição {fim}')

Note também que input já retorna uma string (assumindo que está usando Python 3), então fazer str(input(...)) é redundante e desnecessário. Apenas input já é o suficiente para ter a string.

E para percorrer a string, usei enumerate, que já itera pelos caracteres, juntamente com sua respectiva posição.

Apesar de parecer “pior” só porque “tem mais linhas”, ainda acho melhor que usar count (este método seria válido se você quisesse buscar apenas as ocorrências de uma única letra, mas para mais de uma, não vale a pena ficar percorrendo a string várias vezes sem necessidade).


Se você quisesse somente a quantidade de vezes, uma outra opção é usar um Counter:

from collections import Counter

frase = input('Digite uma frase').lower().strip()
c = Counter(frase)
cont = sum(c[letra] for letra in 'aáâãà')
print(cont)

Mas aí você não teria as posições em que as letras ocorrem (ou seja, continuo sugerindo o primeiro código acima :slight_smile: )


Claro que você pode remover os acentos se quiser, seja usando a biblioteca sugerida aí embaixo, ou usando o módulo nativo unicodedata:

from unicodedata import normalize, combining

sem_acentos = ''.join(c for c in normalize('NFD', frase) if not combining(c))

Só que ainda sim cai no mesmo problema: você vai usar count (que vai percorrer a string inteira uma vez), e depois find e rfind (cada um percorrendo vários caracteres novamente - e no pior caso, a string inteira, caso o caractere não exista), o que eu ainda acho que não é uma boa solução, mesmo que “funcione”.

1 curtida

Pode usar a biblioteca Unidecode para remover os acentos da string.

import unidecode

f = input(‘Digite uma frase:’).lower().strip()
f = unidecode.unidecode(f)

Aí pode procurar por ‘a’ mesmo.

Fazer dessa maneira é interessante se a letra a ser procurada não for hardcoded e sim inserida pelo usuário.

Mas qual o problema que vai causar se a String for percorrida muitas vezes ? Como sou iniciante não sei certas coisas ainda…

Para strings pequenas, rodando poucas vezes, a diferença é imperceptível.

Mas comece a rodar várias vezes (milhares, milhões, etc) com strings maiores, e aí o programa começa a ficar bem mais lento…

Claro que para um exercício, tanto faz. Mas pra projetos reais, com muitos dados, é importante já se acostumar a pensar nesses casos…

1 curtida

Entendi, como esse exercicio é pequeno vou continuar com a biblioteca, mas nos meus projetos pessoais que são maiores vou dar uma boa otimizada, vlw