Nas aulas discutimos o problema de escrever um programa que
leia um texto e indique para cada vogal a lista das suas ocorrências no texto. Trata-se de um problema em que, naturalmente, se opta por um
dicionário para representar o resultado. Assim, para:
txt = 'ernesto ui ui cuidado com os alunos’
o resultado deve ser:
{'e': [0, 3], 'o': [6, 20, 23, 26, 33], 'u': [8, 11, 15, 31], 'i': [9, 12, 16], 'a': [18, 29]}
A solução evidente segue o
padrão ciclo-acumulador. Aqui o acumulador é o dicionário que vai sendo actualizado à medida que percorremos o texto caractere a caractere.
def vogais_x(texto):
dicio = dict()
for i in range(len(texto)):
if texto[i] == 'a':
dicio['a'] = dicio.get('a',[]) + [i]
elif texto[i] == 'e':
dicio['e'] = dicio.get('e',[]) + [i]
elif texto[i] == 'i':
dicio['i'] = dicio.get('i',[]) + [i]
elif texto[i] == 'o':
dicio['o'] = dicio.get('o',[]) + [i]
elif texto[i] == 'u':
dicio['u'] = dicio.get('u',[]) + [i]
else:
continue
return dicio
Todos concordaremos que é uma solução feia. Todos aqueles
ifs podem ser facilmente removidos. Por outro lado, sabemos que vamos precisar não apenas das posições mas também dos caracteres, pelo que nos interessa percorrer o texto obtendo estes dois elementos. Daí uma nova versão:
def vogais_y(texto):
vogais ='aeiou'
dicio = dict()
for i,car in enumerate(texto):
if texto[i] in vogais:
dicio[car] = dicio.get(car,[]) + [i]
return dicio
Estas soluções constroem o dicionário de modo incremental. No entanto, nós sabemos quais são as chaves do dicionário, e sabemos ainda que nunca mudam. Daí , a possibilidade de criar inicialmente o dicionário com as posições todas iguais a listas vazias, recorrendo ao método
fromkeys. Como consequência deixamos de necessitar do uso do método
get.
def vogais(texto):
vogais ='aeiou'
dicio = dict.fromkeys(vogais, [])
for i,car in enumerate(texto):
if car in vogais:
dicio[car] = dicio[car] + [i]
return dicio
O leitor atento dirá que ainda se pode ter uma solução mais elegante usando uma
atribuição aumentada: +=.
def vogais_z(texto):
vogais ='aeiou'
dicio = dict.fromkeys(vogais, [])
for i,car in enumerate(texto):
if car in vogais:
dicio[car] += [i] # <———
return dicio
No entanto, se correr este código verificará que não funciona. Ou melhor, corre mas apresenta o resultado errado:
{'a': [0, 3, 6, 8, 9, 11, 12, 15, 16, 18, 20, 23, 26, 29, 31, 33], 'e': [0, 3, 6, 8, 9, 11, 12, 15, 16, 18, 20, 23, 26, 29, 31, 33], 'i': [0, 3, 6, 8, 9, 11, 12, 15, 16, 18, 20, 23, 26, 29, 31, 33], 'o': [0, 3, 6, 8, 9, 11, 12, 15, 16, 18, 20, 23, 26, 29, 31, 33], 'u': [0, 3, 6, 8, 9, 11, 12, 15, 16, 18, 20, 23, 26, 29, 31, 33]}
A explicação para o resultado (todas as vogais ocorrem nas mesmas posições, igual à união das posições de cada uma…) é simples: a construção do dicionário usando
fromkeys faz com que os valores iniciais sejam o mesmo objecto (partilha de memória) e a instrução
+= não constrói objectos novos. Uma solução consiste em alterar a construção do dicionário inicial, usando
dicionários por compreensão:
def vogais_e(texto):
vogais ='aeiou'
dicio = {vog:[] for vog in 'aeiou'}
for i,car in enumerate(texto):
if car in vogais:
dicio[car] += [i]
return dicio
E pronto. Espero que tenha entendido. Ah, já agora, ainda outra solução….
def vogais_d(texto):
vogais ='aeiou'
dicio = {vog:[] for vog in 'aeiou'}
for i,car in enumerate(texto):
if car in vogais:
dicio[car].append(i)
return dicio
Sem comentários:
Enviar um comentário