⬅ Voltar ao Dashboard Capítulo 6 — Listas

🔍 Pesquisa, For, Range e Enumerate

Seção 6.8–6.11 — Percorrendo listas de forma eficiente

🔎 6.8 Pesquisa

Podemos pesquisar se um elemento está ou não em uma lista, verificando do primeiro ao último elemento se o valor procurado estiver presente. Vejamos a listagem 6.23:

Listagem 6.23 — Pesquisa sequencialL=[15,7,27,39] p=int(input("Digite o valor a procurar:")) achou=False x=0 while x<len(L): if L[x]==p: achou=True break x+=1 if achou: print("%d achado na posição %d" % (p,x)) else: print("%d não encontrado" % p)

A pesquisa simplesmente compara todos os elementos da lista com o valor procurado, interrompendo a repetição ao encontrar o primeiro elemento cujo valor é igual ao procurado. A variável booleana achou será utilizada para verificar se saímos da repetição por termos achado o que procurávamos ou simplesmente porque visitamos todos os elementos sem encontrar o valor procurado. Ela é marcada como True dentro do if com a condição de pesquisa, e antes do break. Assim, achou só será True se algum elemento for igual ao valor procurado.

Exercício 6.8

Modifique o primeiro exemplo (Listagem 6.23) de forma a realizar a mesma tarefa, mas sem utilizar a variável achou. Dica: observe a condição de saída do while.

Exercício 6.9

Modifique o exemplo para pesquisar dois valores. Em vez de apenas p, leia outro valor v que também será procurado. Na impressão, indique qual dos dois valores foi achado primeiro.

Exercício 6.10

Modifique o programa do exercício 6.9 de forma a pesquisar p e v em toda a lista e informando ao usuário a posição onde p e a posição onde v foram encontrados.

🔁 6.9 Usando for

Python apresenta uma estrutura de repetição especialmente projetada para percorrer listas. A instrução for funciona de forma parecida a while, mas a cada repetição utiliza um elemento diferente da lista. A cada repetição, o próximo elemento da lista é utilizado, o que se repete até o fim da lista.

Vamos escrever um programa que utilize for para imprimir todos os elementos de uma lista (Listagem 6.24):

Listagem 6.24 — Impressão de todos os elementos da lista com forL=[8,9,15] for e in L: print(e)

Quando começamos a executar o for, e é igual ao primeiro elemento da lista, no caso, 8, ou seja, L[0]. Em seguida imprimimos 8, e a execução do programa volta para o for, onde passa a valer 9, ou seja, L[1]. Na próxima repetição vai valer 15, ou seja, L[2]. Se tivéssemos que fazer a mesma tarefa com while, teríamos que escrever um programa como o da Listagem 6.25:

Listagem 6.25 — Impressão de todos os elementos da lista com whileL=[8,9,15] x=0 while x<len(L): e=L[x] print(e) x+=1

Embora a instrução for facilite nosso trabalho, ela não substitui completamente o while. Normalmente utilizaremos for quando quisermos processar os elementos de uma lista, um a um. O while é indicado para repetições nas quais não sabemos ainda quantas vezes vamos repetir ou onde manipulamos os índices de forma não sequencial.

A instrução break também interrompe o for. Vejamos a pesquisa escrita usando for, na Listagem 6.26:

Listagem 6.26 — Pesquisa usando forL=[7,9,10,12] p=int(input("Digite um número a pesquisar:")) for e in L: if e == p: print("Elemento encontrado!") break else: print("Elemento não encontrado.")

Utilizamos a instrução break para interromper a busca depois de encontrarmos o primeiro elemento. Em seguida, utilizamos um else, parecido com o da instrução if, para imprimir a mensagem informando que o elemento não foi encontrado. O else do for só será executado se todos os elementos da lista forem visitados, ou seja, se não utilizarmos a instrução break para terminar normalmente.

💡 O else do for é um recurso poderoso e exclusivo do Python. Ele é executado somente quando o laço termina normalmente (sem break), tornando a pesquisa mais legĂ­vel do que usar uma variável booleana auxiliar.

Exercício 6.11

Modifique o programa da listagem 6.15 usando for. Explique por que nem todos os while podem ser transformados em for.

🔢 6.10 Range

Podemos utilizar a função range para gerar listas simples. A função range não retorna uma lista propriamente dita, mas um gerador ou generator. Por enquanto, basta entender como podemos usá-la. Imagine um programa simples que imprime de 0 a 9 na tela (Listagem 6.27):

Listagem 6.27 — Uso da função rangefor v in range(10): print(v)

A função range gerou números de 0 a 9 porque passamos 10 como parâmetro. Ela normalmente gera valores a partir de 0, logo, ao especificarmos apenas 10, estamos apenas informando onde parar. Experimente mudar de 10 para 20. Com a mesma função range, podemos também indicar qual é o primeiro número a gerar, passando dois parâmetros: início e fim (Listagem 6.28):

Listagem 6.28 — Uso da função range com intervalosfor v in range(5, 8): print(v)

Usando 5 como início e 8 como fim, vamos imprimir os números 5, 6 e 7. A notação para o fim é a mesma utilizada com fatias — o fim é um intervalo aberto e não é incluído na faixa de valores. Se acrescentarmos um terceiro parâmetro a range, teremos como saltar entre os valores gerados. Por exemplo, range(0,10,2) gera os pares entre 0 e 10. Vejamos um exemplo que gera os 10 primeiros múltiplos de 3 (Listagem 6.29):

Listagem 6.29 — Uso da função range com saltosfor t in range(3,33,3): print(t, end=" ") print()

Observe que usamos o parâmetro especial end=" ", que indica à função print para não pular de linha após a impressão. No final do programa fizemos uma chamada a print() sem qualquer parâmetro para pular a linha. Para transformar um gerador em lista, utilize a função list (Listagem 6.30):

Listagem 6.30 — Transformação do resultado de range em uma listaL=list(range(100,1100,50)) print(L)

💡 A vantagem de utilizarmos a função range é gerar listas eficientemente, como mostrado no exemplo, sem precisar escrever os 20.000 valores no programa. Experimente list(range(20000))!

🏷️ 6.11 Enumerate

Com a função enumerate podemos ampliar as funcionalidades do for facilmente. Vejamos como imprimir uma lista onde temos o índice entre colchetes e o valor a sua direita.

Primeiro, a abordagem tradicional com um contador manual (Listagem 6.31):

Listagem 6.31 — Impressão de índices sem usar a função enumerateL=[5,9,13] x=0 for e in L: print("[%d] %d" % (x,e)) x+=1

Veja o mesmo programa, mas utilizando a função enumerate na Listagem 6.32:

Listagem 6.32 — Impressão de índices usando a função enumerateL=[5,9,13] for x, e in enumerate(L): print("[%d] %d" % (x,e))

A função enumerate gera uma tupla em que o primeiro valor é o índice e o segundo é o elemento da lista sendo enumerada. Ao utilizarmos x, e em for, indicamos que o primeiro valor da tupla deve ser colocado em x, e o segundo, em e. Assim, na primeira iteração teremos a tupla (0,5), onde x=0 e e=5.

Python permite o desempacotamento de valores de uma tupla, atribuindo um elemento da tupla a cada variável em for. O que temos a cada iteração de for é equivalente a x,e = (0,5), em que o gerador enumerate retorna cada vez uma nova tupla. Os próximos valores retornados são (1,9) e (2,13), respectivamente.

💡 Experimente substituir x,e na Listagem 6.32 por z. Antes do print, faça x,e = z. Adicione mais um print para exibir também o valor de z. Você verá que z é uma tupla!