Python Percorrendo uma Lista

Quase tudo o que se faz com uma lista começa do mesmo jeito: passar pelos itens, um de cada vez. A Ana confere a lista de compras item por item; a professora soma as notas da turma uma a uma; o caixa passa os produtos e vai somando os preços. "Passar por todos os itens" se diz percorrer a lista (em inglês, iterate, "iterar"). Você já conhece a ferramenta, o for (aula for); aqui você vai ver as formas de usá-lo com listas e as tarefas mais comuns: numerar, somar, contar, achar o maior e procurar.

Você vai aprender
  • A percorrer uma lista com for item in lista:, e o costume dos nomes no singular e no plural.
  • Três jeitos de ter o número do item: um contador, range(len(lista)) e enumerate().
  • As tarefas clássicas: somar, contar quem cumpre uma condição, achar o maior, procurar e parar.
  • A percorrer com while, e quando isso faz sentido.
  • Os erros reais: o item usado como índice, o while com <=, o for em len(), a lista inteira no lugar do item e os dois-pontos esquecidos.

A ideia: o dedo que desce pela lista

No mercado, a Ana põe o dedo no primeiro item da lista, pega o produto, desce o dedo para o próximo, pega o produto, e assim até o fim. Ela faz a mesma coisa com cada item; só muda o item da vez. O for é esse dedo: a cada volta, ele aponta para um item e roda o bloco de código com ele.


1. for item in lista

compras = ["arroz", "feijão", "café", "leite"]
for item in compras:
    print(f"Não esqueça: {item}")
print("Pronto, lista conferida!")
for
"Para": a palavra que começa a repetição.
item
A variável que recebe, a cada volta, um item da lista: primeiro "arroz", depois "feijão"… Você escolhe o nome.
in compras
"Em compras": a lista que vai ser percorrida, do primeiro ao último item, na ordem.
:
Os dois-pontos abrem o bloco que se repete.
print(…)
O bloco, com 4 espaços. Roda uma vez para cada item: 4 itens, 4 voltas.
print("Pronto…")
Sem os espaços, já está fora do bloco: roda uma vez só, depois que a lista acabou.
$ python3 percorrer.py
Não esqueça: arroz
Não esqueça: feijão
Não esqueça: café
Não esqueça: leite
Pronto, lista conferida!
Plural para a lista, singular para o item

O costume é dar à lista um nome no plural e à variável do for o mesmo nome no singular: for aluno in alunos, for nota in notas, for preco in precos. Lido em voz alta, faz sentido: "para cada aluno em alunos". E, dentro do bloco, ninguém confunde a lista com o item.

Se a lista estiver vazia, o bloco simplesmente não roda nenhuma vez, e o programa segue em frente sem erro:

compras = []
for item in compras:
    print(item)
print(f"Fim. A lista tinha {len(compras)} itens.")
$ python3 vazia_for.py
Fim. A lista tinha 0 itens.

2. E o número do item?

A Ana quer a lista numerada: "1. arroz", "2. feijão"… O for item in compras dá o item, mas não diz em que volta está. Há três jeitos de ter o número.

Um contador

compras = ["arroz", "feijão", "café", "leite"]
numero = 1
for item in compras:
    print(f"{numero}. {item}")
    numero += 1
$ python3 numerada.py
1. arroz
2. feijão
3. café
4. leite

Uma variável começa em 1 antes do laço e aumenta 1 a cada volta. Funciona, mas são duas linhas a mais, e é fácil esquecer o numero += 1.

range(len(lista)): percorrer os índices

compras = ["arroz", "feijão", "café", "leite"]
for i in range(len(compras)):
    print(f"Índice {i}: {compras[i]}")
$ python3 indices.py
Índice 0: arroz
Índice 1: feijão
Índice 2: café
Índice 3: leite

Aqui o for não percorre a lista: percorre os números 0, 1, 2, 3 (o range(4), aula range()), e o item vem de compras[i]. É o jeito que você usou em Alterando Itens para mudar cada item, porque para escrever em compras[i] é preciso o índice.

enumerate(): o índice e o item juntos

compras = ["arroz", "feijão", "café", "leite"]
for i, item in enumerate(compras):
    print(i, item)
for numero, item in enumerate(compras, start=1):
    print(f"{numero}. {item}")
$ python3 enumerar.py
0 arroz
1 feijão
2 café
3 leite
1. arroz
2. feijão
3. café
4. leite
enumerate(compras)
"Enumerar": a cada volta, entrega dois valores, o número e o item.
for i, item in …
Duas variáveis, separadas por vírgula: a primeira recebe o número, a segunda o item.
start=1
Começa a contar do 1 em vez do 0: perfeito para mostrar a pessoas.

O enumerate é o jeito preferido dos programadores Python: uma linha, sem contador para esquecer, sem compras[i]. Ele tem mais detalhes, que estão na aula enumerate() e zip().

Missão: o programa mostra a lista com colchetes. Troque o print por um for que mostre a lista numerada a partir do 1: 1. arroz, 2. feijão… (use enumerate(compras, start=1) ou um contador).

compras = ["arroz", "feijão", "café", "leite"]
print(compras)
compras = ["arroz", "feijão", "café", "leite"]
for numero, item in enumerate(compras, start=1):
    print(f"{numero}. {item}")

3. Somando: o total do carrinho

A tarefa mais clássica: somar todos os valores. A ideia é ter uma variável que acumula: começa em zero e, a cada volta, recebe mais um valor.

precos = [4.50, 12.00, 8.75, 12.25]
total = 0
for preco in precos:
    total += preco
print(f"Total: R$ {total:.2f}")
print(f"Com sum(): R$ {sum(precos):.2f}")
$ python3 total.py
Total: R$ 37.50
Com sum(): R$ 37.50
  1. Antes do laço: total = 0. O acumulador precisa existir e começar do zero.
  2. Volta 1: total = 0 + 4.50 = 4.50.
  3. Volta 2: 4.50 + 12.00 = 16.50.
  4. Volta 3: 16.50 + 8.75 = 25.25.
  5. Volta 4: 25.25 + 12.25 = 37.50. A lista acabou; o print, fora do bloco, mostra o total.

O :.2f mostra duas casas decimais (aula f-strings). E, para somar uma lista de números, o Python já tem pronta a função sum() (aula Funções Embutidas). Aprender o laço continua valendo a pena: ele serve para tudo o que o sum não faz, como somar só alguns itens ou somar preço × quantidade.


4. Contando e achando o maior

A professora quer saber quantos alunos passaram (nota 6 ou mais) e qual foi a maior nota. Os dois cabem no mesmo laço, cada um com a sua variável:

notas = [7.0, 4.5, 8.5, 6.0, 9.5, 5.0]
aprovados = 0
maior = notas[0]
for nota in notas:
    if nota >= 6:
        aprovados += 1
    if nota > maior:
        maior = nota
print(f"Aprovados: {aprovados} de {len(notas)}")
print(f"Maior nota: {maior}")
$ python3 contar.py
Aprovados: 4 de 6
Maior nota: 9.5
aprovados = 0 … aprovados += 1
Um contador: começa em zero e soma 1 só quando o if é verdadeiro.
maior = notas[0]
O "campeão até agora" começa sendo a primeira nota. (Começar em 0 também daria certo aqui, mas não daria com números negativos; começar pelo primeiro item sempre funciona, desde que a lista não esteja vazia.)
if nota > maior: maior = nota
Cada nota é comparada com o campeão; se for maior, toma o lugar dele.

Para o maior e o menor, o Python também tem funções prontas: max(notas) e min(notas). O laço é o jeito de fazer quando a regra é sua (por exemplo, "o aluno com a maior nota", e não só a nota).


5. Procurando e parando no meio

Para saber se a Carla está na turma, o in basta (aula Listas). Mas às vezes você quer fazer algo quando achar, e não precisa olhar o resto. O break (aula break e continue) para o laço na hora:

turma = ["Ana", "Bruno", "Carla", "Davi", "Eva"]
procurado = "Carla"
for aluno in turma:
    print(f"Olhando {aluno}...")
    if aluno == procurado:
        print(f"Achei {procurado}!")
        break
$ python3 procurar_for.py
Olhando Ana...
Olhando Bruno...
Olhando Carla...
Achei Carla!

O Davi e a Eva nem foram olhados: depois do break, o laço acabou. E se ninguém for achado? O for tem um else que roda só quando o laço chega ao fim sem break; ele tem aula própria: else nos Laços.


6. Percorrendo com while

Também dá para percorrer uma lista com while (aula while), controlando o índice à mão:

compras = ["arroz", "feijão", "café"]
i = 0
while i < len(compras):
    print(i, compras[i])
    i += 1
$ python3 percorrer_while.py
0 arroz
1 feijão
2 café

Três coisas para acertar: o índice começa em 0, a condição é i < len(compras) (menor, e não menor ou igual) e o i += 1 não pode faltar, senão o laço nunca acaba. É muito mais fácil errar do que com o for; por isso, para percorrer uma lista do começo ao fim, use o for. O while faz sentido quando a lista muda durante o laço, como a fila que é atendida até acabar (while fila: fila.pop(0), aula Removendo Itens).


Formas diferentes de percorrer: qual usar

Você precisa deEscrevaObservação
Só os itensfor item in lista:O jeito padrão. Use sempre que puder
O item e o número delefor i, item in enumerate(lista):Com start=1, numera para pessoas
O índice, para alterar a listafor i in range(len(lista)):lista[i] = … dentro do bloco
Os itens de trás para frentefor item in reversed(lista):Veja Ordenando Listas
Ir até a lista acabar, tirando itenswhile lista:A fila: lista.pop(0) dentro do bloco
Uma lista nova a partir de outra[… for item in lista]Aula List Comprehension
A soma, o maior, o menorsum(lista), max(lista), min(lista)Sem laço nenhum

Quando dá errado

Usar o item como se fosse o índice
compras = ["arroz", "feijão", "café"]
for i in compras:
    print(compras[i])
$ python3 erro_indice_str.py
Traceback (most recent call last):
  File "/home/ana/erro_indice_str.py", line 3, in <module>
    print(compras[i])
          ~~~~~~~^^^
TypeError: list indices must be integers or slices, not str

Linha por linha:

  • line 3: o erro foi no print, logo na primeira volta.
  • Os ^^^ marcam o [i]: o índice é o problema.
  • TypeError: list indices must be integers or slices, not str: "os índices de uma lista precisam ser inteiros ou fatias, e não textos".

O nome i enganou: for i in compras põe em i os itens ("arroz", "feijão"…), e não os índices. E compras["arroz"] não faz sentido. Como consertar: se você quer os itens, use-os direto: for item in compras: print(item). Se quer os índices, for i in range(len(compras)):. Dar nomes claros (item para itens, i só para índices) evita esse erro.

O while com <=: uma volta a mais
compras = ["arroz", "feijão", "café"]
i = 0
while i <= len(compras):
    print(compras[i])
    i += 1
$ python3 erro_while.py
arroz
feijão
café
Traceback (most recent call last):
  File "/home/ana/erro_while.py", line 4, in <module>
    print(compras[i])
          ~~~~~~~^^^
IndexError: list index out of range

Os três itens saíram e, só depois, veio o erro. Com <=, o laço rodou também com i valendo 3, e compras[3] não existe (os índices vão de 0 a 2). Como consertar: while i < len(compras):. O mesmo erro acontece com range(len(compras) + 1). Melhor ainda: use o for item in compras, que não tem índice para errar.

for i in len(lista): faltou o range
compras = ["arroz", "feijão", "café"]
for i in len(compras):
    print(compras[i])
$ python3 erro_len.py
Traceback (most recent call last):
  File "/home/ana/erro_len.py", line 2, in <module>
    for i in len(compras):
             ~~~^^^^^^^^^
TypeError: 'int' object is not iterable

"O objeto int não é iterável", ou seja, não dá para percorrer um número. O len(compras) é o número 3, e o for precisa de algo com vários itens. Como consertar: for i in range(len(compras)):, porque é o range que transforma o 3 nos números 0, 1, 2.

A lista inteira no lugar do item
compras = ["arroz", "feijão", "café"]
for item in compras:
    print(f"Comprar: {compras}")
$ python3 erro_lista_toda.py
Comprar: ['arroz', 'feijão', 'café']
Comprar: ['arroz', 'feijão', 'café']
Comprar: ['arroz', 'feijão', 'café']

Sem erro, mas a lista inteira saiu três vezes. Dentro do bloco, a Ana escreveu compras (a lista) em vez de item (o item da vez). O laço rodou 3 vezes, como devia, e mostrou a mesma coisa em todas. Como consertar: print(f"Comprar: {item}").

Os dois-pontos esquecidos
compras = ["arroz", "feijão", "café"]
for item in compras
    print(item)
$ python3 erro_ponto.py
  File "/home/ana/erro_ponto.py", line 2
    for item in compras
                       ^
SyntaxError: expected ':'

"Esperava :". O ^ aponta para o fim da linha 2, exatamente onde os dois-pontos deveriam estar. Como todo SyntaxError, nada rodou. Como consertar: for item in compras:.

Tirar ou pôr itens enquanto percorre

Remover itens da lista dentro de um for que anda por ela pula itens, sem erro nenhum. Você viu o porquê, passo a passo, em Removendo Itens. E alterar a variável do laço (item = …) não altera a lista: veja Alterando Itens.


Referência rápida

EscritaA cada volta, você tem
for item in lista:O item
for i in range(len(lista)):O índice (o item é lista[i])
for i, item in enumerate(lista):O índice (do 0) e o item
for n, item in enumerate(lista, start=1):O número (do 1) e o item
i = 0 / while i < len(lista): / i += 1O índice, controlado à mão
TarefaAntes do laçoDentro do laçoPronto
Somartotal = 0total += valorsum(lista)
Contar quem cumpre uma condiçãoconta = 0if condição: conta += 1—
Achar o maiormaior = lista[0]if valor > maior: maior = valormax(lista)
Procurar e parar—if achou: … breakx in lista (só para saber se está)
Montar outra listanova = []nova.append(…)List comprehension
SintomaCausa provável
TypeError: list indices must be integers or slices, not strfor i in lista deu itens, e você usou lista[i]
IndexError: list index out of range depois do último itemwhile i <= len(lista) ou range(len(lista) + 1)
TypeError: 'int' object is not iterablefor i in len(lista): faltou o range
A lista inteira se repete na saídaUsou o nome da lista no lugar da variável do laço
SyntaxError: expected ':'Faltaram os dois-pontos no fim do for
O laço nunca termina (while)Faltou o i += 1

Exercícios

1. Para cada aluno

Complete o laço que mostra cada aluno da lista alunos:

aluno alunos:
    print(aluno)

2. Contando a partir do 1

Complete para o enumerate começar do 1:

for n, item in enumerate(compras, start=):

3. Quantas voltas?

Quantas vezes o bloco de for nota in []: roda?

4. Em for x in ["a", "b", "c"]:, o que x vale na segunda volta?

5. Qual laço percorre os índices de uma lista de 3 itens sem erro?

6. Para somar uma lista de preços com um laço, o que vem antes do for?

Missão final: o caixa do mercado

Missão: complete o laço para o programa mostrar o total da compra e quantos itens custam mais de R$ 10. Faça com o for (sem sum).

precos = [4.50, 12.00, 8.75, 12.25]
total = 0
caros = 0
for preco in precos:
    pass  # troque esta linha
print(f"Total: R$ {total:.2f}")
print(f"Itens acima de R$ 10: {caros}")
precos = [4.50, 12.00, 8.75, 12.25]
total = 0
caros = 0
for preco in precos:
    total += preco
    if preco > 10:
        caros += 1
print(f"Total: R$ {total:.2f}")
print(f"Itens acima de R$ 10: {caros}")

O pass do código inicial é uma instrução que não faz nada: ele só segura o lugar do bloco, que não pode ficar vazio.


Resumo

  • for item in lista: roda o bloco uma vez para cada item, na ordem. Lista vazia: zero voltas, sem erro.
  • Nome da lista no plural, da variável no singular: for nota in notas.
  • Para ter o número: enumerate(lista) (com start=1 para pessoas); para alterar a lista: range(len(lista)).
  • Somar, contar e achar o maior seguem a mesma receita: uma variável criada antes do laço e atualizada dentro. Para os casos simples, existem sum, max e min.
  • break para o laço quando você achou o que procurava.
  • O while também percorre, mas é fácil errar (<=, i += 1 esquecido); prefira o for.
  • for i in lista dá itens, não índices: lista[i] ali dá TypeError.