Python enumerate() e zip()
O for percorre uma lista item por item. Mas duas perguntas aparecem logo: "em que posição está este item?" (para numerar uma lista de compras) e "como andar em duas listas ao mesmo tempo?" (os nomes dos alunos numa lista, as notas em outra). Para a primeira, existe a função embutida enumerate(); para a segunda, a zip(). As duas deixam o for mais curto e mais claro, e evitam um dos jeitos mais desajeitados de escrever um laço: o range(len(lista)).
- A numerar os itens de um
forcomenumerate(), começando do 0 ou do 1 (start=1). - A percorrer duas ou três listas lado a lado com
zip(). - O que o
zip()faz quando as listas têm tamanhos diferentes, e como a opçãostrict=Truetransforma isso num erro. - A montar um dicionário com
dict(zip(…)). - A usar os dois juntos para fazer um ranking.
- Os erros reais:
ValueError: too many values to unpackeValueError: zip() argument 2 is shorter than argument 1.
A ideia: a senha da fila e o zíper
Na padaria do bairro, cada pessoa que chega pega uma senha: 1, 2, 3… A pessoa continua sendo a mesma, mas agora vem acompanhada de um número. É o que o enumerate() faz: entrega cada item da lista junto com o número da posição dele. O nome vem do inglês enumerate, "enumerar", "numerar um por um".
Agora pense num zíper de casaco. Ele tem dois lados com dentes, e ao fechar, cada dente de um lado se encaixa no dente correspondente do outro: o primeiro com o primeiro, o segundo com o segundo. A função zip() (é esse o nome, "zíper" em inglês) faz isso com listas: junta o primeiro item de uma com o primeiro da outra, o segundo com o segundo, e assim por diante.
1. enumerate(): o item e a sua posição
fila = ["Ana", "Bruno", "Clara"]
for posicao, nome in enumerate(fila):
print(posicao, nome)
$ python3 fila.py 0 Ana 1 Bruno 2 Clara
- enumerate(fila)
- Em cada volta do laço, entrega dois valores: a posição e o item.
- for posicao, nome in …
- Duas variáveis no
for, separadas por vírgula: a primeira recebe a posição; a segunda, o item. É o desempacotamento que você viu na aula Desempacotamento. - 0, 1, 2
- A contagem começa do zero, igual aos índices da lista (aula Acessando Itens):
fila[0]é"Ana".
O que o enumerate() entrega, por dentro
No modo interativo, dá para espiar. O enumerate() sozinho não mostra os pares; para vê-los, transforme em lista com list():
$ python3 Python 3.14.4 (main, Aug 20 2026, 10:41:58) [GCC 15.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> fila = ["Ana", "Bruno", "Clara"] >>> enumerate(fila) <enumerate object at 0x7fb1290e75b0> >>> list(enumerate(fila)) [(0, 'Ana'), (1, 'Bruno'), (2, 'Clara')]
<enumerate object at 0x7fb1290e75b0> quer dizer "um objeto enumerate, guardado no endereço tal da memória". (Esse número muda a cada execução; não se preocupe com ele.) O enumerate() não monta uma lista: ele vai entregando os pares um de cada vez, conforme o for pede. Com list(), você vê todos: são tuplas (aula Tuplas), cada uma com a posição e o item.
Começando do 1: start=1
Para as pessoas, listas começam do 1. Ninguém escreve "item 0: arroz" numa lista de compras. A opção start ("começo") diz de qual número a contagem parte:
compras = ["arroz", "feijão", "café", "leite"]
print("Lista de compras:")
for numero, item in enumerate(compras, start=1):
print(f"{numero}. {item}")
$ python3 compras.py Lista de compras: 1. arroz 2. feijão 3. café 4. leite
>>> list(enumerate(fila, start=1)) [(1, 'Ana'), (2, 'Bruno'), (3, 'Clara')]
O start=1 muda só o número que aparece. A lista continua a mesma: compras[0] ainda é "arroz".
Missão: a lista da Ana está saindo numerada a partir do 0. Faça a numeração começar do 1, mudando só a chamada do enumerate().
compras = ["arroz", "feijão", "café", "leite"]
for numero, item in enumerate(compras):
print(f"{numero}. {item}")
compras = ["arroz", "feijão", "café", "leite"]
for numero, item in enumerate(compras, start=1):
print(f"{numero}. {item}")
Sem o enumerate(): os jeitos antigos
Antes de conhecer o enumerate(), muita gente numera de um destes dois jeitos:
compras = ["arroz", "feijão", "café", "leite"]
numero = 1
for item in compras:
print(f"{numero}. {item}")
numero = numero + 1
for i in range(len(compras)):
print(f"{i + 1}. {compras[i]}")
$ python3 contador_manual.py 1. arroz 2. feijão 3. café 4. leite 1. arroz 2. feijão 3. café 4. leite
Os dois funcionam, mas cada um tem um ponto fraco. No primeiro, você cuida do contador à mão: se esquecer o numero = numero + 1 (ou colocá-lo fora do laço), todos os itens saem com o número 1. No segundo, o range(len(compras)) percorre os números, e o item só aparece por compras[i], com colchetes e mais uma chance de errar o índice. O enumerate() entrega as duas coisas prontas.
2. zip(): duas listas lado a lado
A professora guardou os nomes dos alunos numa lista e as notas em outra, na mesma ordem: a primeira nota é da Ana, a segunda é do Bruno, a terceira é da Clara.
alunos = ["Ana", "Bruno", "Clara"]
notas = [9.0, 6.5, 8.0]
for aluno, nota in zip(alunos, notas):
situacao = "aprovado" if nota >= 7 else "recuperação"
print(f"{aluno}: {nota} ({situacao})")
$ python3 boletim_zip.py Ana: 9.0 (aprovado) Bruno: 6.5 (recuperação) Clara: 8.0 (aprovado)
- zip(alunos, notas)
- Fecha o zíper: junta o 1º aluno com a 1ª nota, o 2º com a 2ª, o 3º com a 3ª.
- for aluno, nota in …
- Em cada volta, um par:
alunorecebe o item da primeira lista;nota, o da segunda. A ordem das variáveis é a ordem das listas nozip(). - "aprovado" if nota >= 7 else "recuperação"
- Um
ifnuma linha só (aula if em uma Linha), só para enfeitar o boletim.
Por dentro, também são tuplas:
>>> alunos = ["Ana", "Bruno", "Clara"]
>>> notas = [9.0, 6.5, 8.0]
>>> list(zip(alunos, notas))
[('Ana', 9.0), ('Bruno', 6.5), ('Clara', 8.0)]
Missão: o programa mostra só os nomes. Use zip() para mostrar cada aluno com a sua nota, no formato Ana: 9.0.
alunos = ["Ana", "Bruno", "Clara"]
notas = [9.0, 6.5, 8.0]
for aluno in alunos:
print(aluno)
alunos = ["Ana", "Bruno", "Clara"]
notas = [9.0, 6.5, 8.0]
for aluno, nota in zip(alunos, notas):
print(f"{aluno}: {nota}")
Três listas (ou mais)
O zip() aceita quantas listas você quiser. A cada volta, vem um item de cada uma:
produtos = ["arroz", "café", "sal"]
precos = [25.9, 18.5, 3.2]
quantidades = [2, 1, 3]
total = 0
for produto, preco, quantidade in zip(produtos, precos, quantidades):
subtotal = preco * quantidade
total = total + subtotal
print(f"{quantidade} x {produto}: R$ {subtotal:.2f}")
print(f"Total: R$ {total:.2f}")
$ python3 tres_listas.py 2 x arroz: R$ 51.80 1 x café: R$ 18.50 3 x sal: R$ 9.60 Total: R$ 79.90
Montando um dicionário: dict(zip(…))
Uma lista de chaves e uma lista de valores, juntas pelo zip(), viram um dicionário (aula Dicionários):
>>> dict(zip(alunos, notas))
{'Ana': 9.0, 'Bruno': 6.5, 'Clara': 8.0}
3. Listas de tamanhos diferentes
Chegou um aluno novo, o Davi, e a professora pôs o nome dele na lista. Mas ainda não lançou a nota:
alunos = ["Ana", "Bruno", "Clara", "Davi"]
notas = [9.0, 6.5, 8.0]
for aluno, nota in zip(alunos, notas):
print(aluno, nota)
print("Fim")
$ python3 tamanhos.py Ana 9.0 Bruno 6.5 Clara 8.0 Fim
O Davi sumiu, e sem aviso nenhum. O zip() para assim que a lista mais curta acaba: depois da Clara, não há mais nota para encaixar, então o zíper termina ali. Isso pode ser exatamente o que você quer… ou pode esconder um erro de verdade, como uma nota que alguém esqueceu de lançar.
strict=True: exigir o mesmo tamanho
Quando as listas têm de ter o mesmo tamanho, diga isso ao zip() com a opção strict=True ("estrito", "rigoroso"). Aí, em vez de cortar calado, ele dá erro:
alunos = ["Ana", "Bruno", "Clara", "Davi"]
notas = [9.0, 6.5, 8.0]
for aluno, nota in zip(alunos, notas, strict=True):
print(aluno, nota)
print("Fim")
$ python3 estrito.py
Ana 9.0
Bruno 6.5
Clara 8.0
Traceback (most recent call last):
File "/home/ana/estrito.py", line 4, in <module>
for aluno, nota in zip(alunos, notas, strict=True):
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: zip() argument 2 is shorter than argument 1
- Ana 9.0 … Clara 8.0
- As três primeiras voltas aconteceram normalmente. O
zip()só descobre que faltou uma nota quando tenta montar o quarto par. - line 4, in <module>
- O erro aconteceu na linha do
for, a dozip(); as marcas~~~^^^apontam para ele. - ValueError: zip() argument 2 is shorter than argument 1
- "Erro de valor: o argumento 2 do
zip()é mais curto que o argumento 1." O argumento 1 éalunos(4 itens); o 2 énotas(3 itens). Se fosse o contrário, a mensagem diriais longer than, "é mais longo que". - Fim (não apareceu)
- O programa parou no erro. Melhor assim: um boletim sem a nota do Davi não pode passar despercebido.
strict=True
Sempre que as listas representam a mesma coisa (o nome e a nota do mesmo aluno, o produto e o preço do mesmo produto), use strict=True. Se um dia uma lista ficar maior que a outra, você descobre na hora, em vez de receber um resultado errado em silêncio.
4. Os dois juntos: o ranking
As notas já estão em ordem, da maior para a menor. Para mostrar o ranking, você precisa do lugar (enumerate) e do par aluno-nota (zip):
alunos = ["Clara", "Ana", "Bruno"]
notas = [9.5, 8.0, 7.0]
for lugar, (aluno, nota) in enumerate(zip(alunos, notas), start=1):
print(f"{lugar}º lugar: {aluno} com {nota}")
$ python3 ranking.py 1º lugar: Clara com 9.5 2º lugar: Ana com 8.0 3º lugar: Bruno com 7.0
- zip(alunos, notas)
- Primeiro, os pares:
('Clara', 9.5),('Ana', 8.0),('Bruno', 7.0). - enumerate(…, start=1)
- Depois, cada par ganha um número:
(1, ('Clara', 9.5))… - lugar, (aluno, nota)
- O desempacotamento acompanha o formato: o número vai para
lugar, e o par, entre parênteses, se abre emalunoenota. Sem os parênteses (for lugar, aluno, nota in …), o Python tentaria distribuir os 2 valores de cada volta (o número e o par) em 3 variáveis, e pararia comValueError: not enough values to unpack (expected 3, got 2): "valores de menos para desempacotar (esperava 3, recebeu 2)".
Formas diferentes de fazer a mesma coisa
Mostrar cada aluno com a sua nota, de três jeitos:
for i in range(len(alunos)):
print(alunos[i], notas[i])
for i, aluno in enumerate(alunos):
print(aluno, notas[i])
for aluno, nota in zip(alunos, notas, strict=True):
print(aluno, nota)
| Forma | Quando usar |
|---|---|
zip(alunos, notas, strict=True) | Para andar em duas listas juntas. É a mais clara: sem índice, sem colchetes, e avisa se os tamanhos não baterem |
enumerate(lista) | Quando você precisa do número da posição: para numerar, ou para mudar o item com lista[i] = … |
range(len(lista)) | Evite. Funciona, mas é mais longo e mais fácil de errar. Se a outra lista for mais curta, dá IndexError no meio do laço |
Quando dá errado
for, mas sem o enumerate()
A Ana queria numerar a lista, escreveu as duas variáveis no for… e esqueceu o enumerate():
compras = ["arroz", "feijão", "café"]
for numero, item in compras:
print(numero, item)
$ python3 sem_enumerate.py
Traceback (most recent call last):
File "/home/ana/sem_enumerate.py", line 3, in <module>
for numero, item in compras:
^^^^^^^^^^^^
ValueError: too many values to unpack (expected 2)
- line 3
- O erro está na linha do
for. - ^^^^^^^^^^^^
- As marcas apontam para
numero, item: o problema está em distribuir o valor nas duas variáveis. - ValueError: too many values to unpack (expected 2)
- "Valores demais para desempacotar (esperava 2)." Sem o
enumerate(), cada volta entrega um item só: o texto"arroz". O Python tenta abrir esse texto em duas variáveis, como faria com uma tupla, e encontra cinco letras para duas variáveis.
Como consertar: for numero, item in enumerate(compras, start=1):.
zip duas vezes
Assim como o enumerate(), o zip() entrega os pares um de cada vez, e só uma vez. Se você guarda o resultado numa variável e percorre duas vezes, a segunda vem vazia, sem erro:
>>> pares = zip(alunos, notas)
>>> list(pares)
[('Ana', 9.0), ('Bruno', 6.5), ('Clara', 8.0)]
>>> list(pares)
[]
O zíper já foi fechado até o fim; não há mais nada para entregar. Como consertar: chame o zip() de novo, direto no for (for aluno, nota in zip(alunos, notas):), ou guarde uma lista com pares = list(zip(alunos, notas)), que pode ser percorrida quantas vezes você quiser. A aula Iteradores explica por que isso acontece.
Missão: rode e veja o ValueError: falta a nota do Davi. Ele tirou 7.5. Acrescente a nota que falta (mantenha o strict=True).
alunos = ["Ana", "Bruno", "Clara", "Davi"]
notas = [9.0, 6.5, 8.0]
for aluno, nota in zip(alunos, notas, strict=True):
print(aluno, nota)
alunos = ["Ana", "Bruno", "Clara", "Davi"]
notas = [9.0, 6.5, 8.0, 7.5]
for aluno, nota in zip(alunos, notas, strict=True):
print(aluno, nota)
Referência rápida
| Escrita | O que entrega |
|---|---|
enumerate(lista) | Pares (posição, item), começando do 0 |
enumerate(lista, start=1) | Pares (número, item), começando do 1 |
for i, item in enumerate(lista): | Percorre com o número e o item |
zip(a, b) | Pares (item de a, item de b), até a lista mais curta acabar |
zip(a, b, c) | Trios, um item de cada lista |
zip(a, b, strict=True) | Igual, mas dá ValueError se os tamanhos forem diferentes |
dict(zip(chaves, valores)) | Um dicionário |
list(enumerate(…)), list(zip(…)) | Uma lista com todas as tuplas (para ver, ou para usar mais de uma vez) |
for n, (a, b) in enumerate(zip(x, y), start=1): | Os dois juntos |
| Sintoma | Causa provável |
|---|---|
ValueError: too many values to unpack (expected 2) num for | Duas variáveis no for, mas faltou o enumerate() ou o zip() |
ValueError: zip() argument 2 is shorter than argument 1 | strict=True e a segunda lista tem menos itens (com is longer than, mais itens) |
| Itens somem no fim, sem erro | Listas de tamanhos diferentes num zip() sem strict=True |
A segunda volta num zip guardado não mostra nada | O zip (e o enumerate) só pode ser percorrido uma vez |
<enumerate object at 0x…> ou <zip object at 0x…> | Você mostrou o objeto, não os pares: use list(…) ou um for |
Exercícios
1. Numerando a partir do 1
Complete para a numeração começar do 1:
2. O zíper
Complete para percorrer os produtos e os preços juntos:
3. alunos tem 4 nomes e notas tem 3 notas. Quantas voltas dá o for aluno, nota in zip(alunos, notas):?
4. O que list(enumerate(["a", "b"])) devolve?
5. Para que serve o strict=True no zip()?
Missão final: o pódio
Missão: mostre o pódio da gincana, no formato 1º lugar: Clara (95 pontos), usando enumerate() e zip() juntos, com a contagem começando do 1.
nomes = ["Clara", "Ana", "Bruno"] pontos = [95, 80, 70] # escreva o for aqui
nomes = ["Clara", "Ana", "Bruno"]
pontos = [95, 80, 70]
for lugar, (nome, ponto) in enumerate(zip(nomes, pontos), start=1):
print(f"{lugar}º lugar: {nome} ({ponto} pontos)")
Resumo
enumerate(lista)entrega cada item junto com a sua posição:for i, item in enumerate(lista):. Começa do 0; comstart=1, do 1.zip(a, b)anda em duas (ou mais) listas ao mesmo tempo, item com item, como um zíper.- Com tamanhos diferentes, o
zip()para na lista mais curta, sem avisar. Comstrict=True, dáValueError: zip() argument 2 is shorter than argument 1. dict(zip(chaves, valores))monta um dicionário.- Juntos:
for n, (a, b) in enumerate(zip(x, y), start=1):. enumerateezipentregam os pares um de cada vez, e só uma vez. Para ver todos ou reaproveitar, uselist(…).- Prefira os dois ao
range(len(lista)): menos colchetes, menos chances de errar.