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:
1.
txt
=
'ernesto ui ui cuidado com os alunos’
o resultado deve ser:
1.
{
'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.
01.
def
vogais_x(texto):
02.
dicio
=
dict()
03.
for
i
in
range(len(texto)):
04.
if
texto[i]
=
=
'a'
:
05.
dicio[
'a'
]
=
dicio.get(
'a'
,[])
+
[i]
06.
elif
texto[i]
=
=
'e'
:
07.
dicio[
'e'
]
=
dicio.get(
'e'
,[])
+
[i]
08.
elif
texto[i]
=
=
'i'
:
09.
dicio[
'i'
]
=
dicio.get(
'i'
,[])
+
[i]
10.
elif
texto[i]
=
=
'o'
:
11.
dicio[
'o'
]
=
dicio.get(
'o'
,[])
+
[i]
12.
elif
texto[i]
=
=
'u'
:
13.
dicio[
'u'
]
=
dicio.get(
'u'
,[])
+
[i]
14.
else
:
15.
continue
16.
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:
1.
def
vogais_y(texto):
2.
vogais
=
'aeiou'
3.
dicio
=
dict()
4.
for
i,car
in
enumerate(texto):
5.
if
texto[i]
in
vogais:
6.
dicio[car]
=
dicio.get(car,[])
+
[i]
7.
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.
1.
def
vogais(texto):
2.
vogais
=
'aeiou'
3.
dicio
=
dict.fromkeys(vogais, [])
4.
for
i,car
in
enumerate(texto):
5.
if
car
in
vogais:
6.
dicio[car]
=
dicio[car]
+
[i]
7.
return
dicio
O leitor atento dirá que ainda se pode ter uma solução mais elegante usando uma
atribuição aumentada: +=.
1.
def
vogais_z(texto):
2.
vogais
=
'aeiou'
3.
dicio
=
dict.fromkeys(vogais, [])
4.
for
i,car
in
enumerate(texto):
5.
if
car
in
vogais:
6.
dicio[car]
+
=
[i]
7.
return
dicio
No entanto, se correr este código verificará que não funciona. Ou melhor, corre mas apresenta o resultado errado:
1.
{
'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:
1.
def
vogais_e(texto):
2.
vogais
=
'aeiou'
3.
dicio
=
{vog:[]
for
vog
in
'aeiou'
}
4.
for
i,car
in
enumerate(texto):
5.
if
car
in
vogais:
6.
dicio[car]
+
=
[i]
7.
return
dicio
E pronto. Espero que tenha entendido. Ah, já agora, ainda outra solução….
1.
def
vogais_d(texto):
2.
vogais
=
'aeiou'
3.
dicio
=
{vog:[]
for
vog
in
'aeiou'
}
4.
for
i,car
in
enumerate(texto):
5.
if
car
in
vogais:
6.
dicio[car].append(i)
7.
return
dicio
Sem comentários:
Enviar um comentário