Python Desempacotamento

Na aula Tuplas, a data de nascimento da Ana virou (12, 3, 1990), e para usar cada parte era preciso escrever aniversario[0], aniversario[1], aniversario[2]. Funciona, mas ninguém lembra o que é o [1]. O desempacotamento (em inglês, unpacking) resolve isso: numa linha só, cada valor da tupla vai para uma variável com nome: dia, mes, ano = aniversario.

Você vai aprender
  • A desempacotar uma tupla (ou lista, ou texto) em várias variáveis de uma vez.
  • A trocar o valor de duas variáveis com a, b = b, a, e por que o jeito "óbvio" não funciona.
  • A juntar "o resto" numa lista com o asterisco: primeira, *resto = notas.
  • A ignorar valores com _ e a desempacotar dentro do for.
  • Os erros reais: too many values to unpack, not enough values to unpack e companhia.

A ideia: desfazer a mala

A Ana chega de viagem com uma mala que tem três coisas: uma camiseta, uma calça e um tênis. Desfazer a mala é tirar cada coisa e pôr no seu lugar: a camiseta na gaveta de cima, a calça na do meio, o tênis na sapateira. Uma coisa para cada lugar, na ordem.

Desempacotar é isso. A tupla é a mala; as variáveis à esquerda do = são os lugares. O Python tira o primeiro valor e põe na primeira variável, o segundo na segunda, e assim por diante. A regra de ouro: o número de lugares tem de ser igual ao número de coisas. Sobrou coisa ou faltou coisa, o Python reclama.


1. O primeiro desempacotamento

aniversario = (12, 3, 1990)
dia, mes, ano = aniversario
print(dia)
print(mes)
print(ano)
print(f"Nasci em {dia}/{mes}/{ano}")
aniversario = (12, 3, 1990)
A "mala": uma tupla com três valores.
dia, mes, ano
Três variáveis separadas por vírgula, do lado esquerdo do =. São os três "lugares".
=
A atribuição de sempre. Só que, com várias variáveis à esquerda, o Python desempacota o valor da direita.
resultado
dia recebe 12, mes recebe 3, ano recebe 1990. Na ordem: primeiro com primeiro, segundo com segundo.
$ python3 d_basico.py
12
3
1990
Nasci em 12/3/1990

Compare com a aula anterior: f"Nasci em {dia}/{mes}/{ano}" se lê muito melhor que f"Nasci em {aniversario[0]}/{aniversario[1]}/{aniversario[2]}". Esse é o ganho do desempacotamento: nomes no lugar de números.


2. Não é só tupla

Dá para desempacotar qualquer coisa que tenha itens em sequência: listas, textos (letra por letra) e até uma tupla escrita ali mesmo, sem parênteses.

nome, idade = ["Ana", 34]
print(nome, idade)
a, b, c = "sol"
print(a, b, c)
x, y = 10, 20
print(x, y)
$ python3 d_fontes.py
Ana 34
s o l
10 20

A última forma, x, y = 10, 20, é a que você já viu na aula Atribuição Múltipla. Agora dá para entender o que acontece por dentro: 10, 20 é uma tupla (a vírgula faz a tupla, lembra?), e o Python a desempacota em x e y.


3. A troca: a, b = b, a

A Ana tem duas variáveis, a com "café" e b com "chá", e quer trocar: a fica com o chá e b com o café. O jeito que parece óbvio dá errado:

a = "café"
b = "chá"
a = b
b = a
print(a, b)
$ python3 d_troca_errada.py
chá chá

Os dois ficaram com chá. Na linha 3, a = b pôs "chá" em a, e o "café" se perdeu: nenhuma variável guarda mais esse valor. Na linha 4, b = a copiou o chá de volta. É como trocar o conteúdo de dois copos sem um terceiro copo: não dá.

O jeito clássico, em muitas linguagens, é usar um terceiro copo, uma variável auxiliar:

a = "café"
b = "chá"
guarda = a
a = b
b = guarda
print(a, b)
$ python3 d_troca_aux.py
chá café

Em Python existe um jeito mais curto, com desempacotamento:

a = "café"
b = "chá"
print("Antes:", a, b)
a, b = b, a
print("Depois:", a, b)
$ python3 d_troca.py
Antes: café chá
Depois: chá café
  1. O Python calcula primeiro o lado direito inteiro: b, a vira a tupla ("chá", "café"). Os dois valores ficam guardados nessa tupla.
  2. Só depois ele desempacota a tupla no lado esquerdo: a recebe "chá", b recebe "café".
  3. Nada se perde, porque a tupla fez o papel do terceiro copo, sem você precisar criá-lo.

Missão: troque os valores de a e b com uma linha só, usando desempacotamento, para o programa mostrar a = chá e b = café.

a = "café"
b = "chá"
# escreva a troca aqui
print("a =", a)
print("b =", b)
a = "café"
b = "chá"
a, b = b, a
print("a =", a)
print("b =", b)

4. O asterisco: "e o resto"

E quando você quer só o primeiro valor, e o resto junto? A Ana tem as notas do bimestre e quer separar a primeira das outras. Com um * antes do nome, a variável vira uma lista que recolhe tudo o que sobrou:

notas = (8, 10, 6, 10, 9)
primeira, *resto = notas
print(primeira)
print(resto)
*inicio, ultima = notas
print(inicio)
print(ultima)
primeira, *meio, ultima = notas
print(primeira, meio, ultima)
$ python3 d_estrela.py
8
[10, 6, 10, 9]
[8, 10, 6, 10]
9
8 [10, 6, 10] 9
primeira, *resto = notas
primeira pega o primeiro valor (8). *resto pega todo o resto, numa lista.
*inicio, ultima = notas
O asterisco pode vir antes: ultima pega o último valor (9) e inicio recolhe o que vem antes dele.
primeira, *meio, ultima = notas
Ou no meio: primeiro e último com nome, e o miolo numa lista.
[ … ]
Repare nos colchetes: a variável com asterisco é sempre uma lista, mesmo que a origem seja uma tupla.

Se não sobrar nada para o asterisco, ele fica com uma lista vazia. Não é erro:

primeiro, *resto = ["só eu"]
print(primeiro)
print(resto)
$ python3 d_estrela_vazia.py
só eu
[]

Com o asterisco, a regra de ouro fica mais flexível: as variáveis sem asterisco precisam de um valor cada, e o asterisco aceita qualquer quantidade, até zero. Mas só pode haver um asterisco por desempacotamento (veja Quando dá errado).


5. Ignorando valores com _

Às vezes você não precisa de um dos valores. O costume em Python é dar a ele o nome _ (sublinhado), que quer dizer "não me interessa":

nome, _, cidade = ("Ana", 34, "Teresina")
print(nome, "mora em", cidade)
primeiro, *_ = ("seg", "ter", "qua")
print(primeiro)
$ python3 d_ignorar.py
Ana mora em Teresina
seg

O _ é uma variável comum; o Python guarda o 34 nela normalmente. O nome é só um recado para quem lê: "este valor eu descartei de propósito". E *_ descarta todo o resto.


6. Desempacotando no for

Aqui o desempacotamento brilha. Uma lista de tuplas é muito comum: cada tupla é um "registro" (um aluno e sua nota, um produto e seu preço). No for, você desempacota cada tupla direto nas variáveis do laço:

turma = [("Ana", 9), ("Bia", 7), ("Caio", 8)]
for nome, nota in turma:
    print(f"{nome} tirou {nota}")
$ python3 d_for.py
Ana tirou 9
Bia tirou 7
Caio tirou 8

A cada volta, o for pega uma tupla, por exemplo ("Ana", 9), e faz nome, nota = ("Ana", 9). Sem desempacotar, você escreveria for aluno in turma: e depois aluno[0] e aluno[1]. Esse mesmo truque aparece de novo em Percorrendo um Dicionário e em enumerate() e zip().

Funções que devolvem dois valores

Algumas funções do Python devolvem uma tupla, justamente para você desempacotar. A divmod(a, b) devolve o resultado da divisão inteira e o resto, juntos. Com 17 ovos e caixas de 5:

caixas, sobram = divmod(17, 5)
print("Caixas cheias:", caixas)
print("Ovos que sobram:", sobram)
$ python3 d_divmod.py
Caixas cheias: 3
Ovos que sobram: 2

Quando você aprender a criar suas próprias funções, vai ver que return a, b faz a mesma coisa: devolve uma tupla (aula return).


7. O asterisco do outro lado: espalhar no print

O * também funciona ao contrário: na hora de chamar uma função, *dias espalha os itens como se você tivesse escrito cada um separado por vírgula.

dias = ("seg", "ter", "qua")
print(dias)
print(*dias)
print(*dias, sep=" - ")
$ python3 d_print.py
('seg', 'ter', 'qua')
seg ter qua
seg - ter - qua

print(*dias) é o mesmo que print("seg", "ter", "qua"): três valores separados, que o print mostra com espaço entre eles (ou com o sep que você escolher, como na aula As Opções sep e end).


Formas diferentes de fazer a mesma coisa

ObjetivoSem desempacotarDesempacotando
Pegar as partes de uma datadia = data[0]
mes = data[1]
ano = data[2]
dia, mes, ano = data
Trocar duas variáveisguarda = a
a = b
b = guarda
a, b = b, a
Primeiro item e o restoprimeira = notas[0]
resto = list(notas[1:])
primeira, *resto = notas
Percorrer uma lista de paresfor aluno in turma:
print(aluno[0], aluno[1])
for nome, nota in turma:
print(nome, nota)

Qual usar? Desempacotar quando você sabe quantos valores vêm e quer todos com nome: o código fica mais curto e mais claro. Use índice (data[0]) quando precisa de um item só, numa tupla grande.


Quando dá errado

Sobraram valores: too many values to unpack
dia, mes = (12, 3, 1990)
$ python3 d_muitos.py
Traceback (most recent call last):
  File "/home/ana/d_muitos.py", line 1, in <module>
    dia, mes = (12, 3, 1990)
    ^^^^^^^^
ValueError: too many values to unpack (expected 2, got 3)
File "/home/ana/d_muitos.py", line 1
O erro está na linha 1.
^^^^^^^^
Os acentos circunflexos marcam dia, mes: o lado esquerdo, onde estão os "lugares".
ValueError
"Erro de valor": o tipo está certo (é uma tupla), mas ela não serve do jeito que veio.
too many values to unpack
"Valores demais para desempacotar". Vieram mais coisas do que lugares.
(expected 2, got 3)
"Esperava 2, recebeu 3": duas variáveis, três valores. O 1990 ficou sem lugar.

Como consertar: uma variável para cada valor (dia, mes, ano = …), ou recolha o que sobra: dia, mes, *_ = ….

Em versões mais antigas do Python 3.14

O "got 3" (quantos valores vieram) é novidade do Python 3.14. No Python 3.13, que vem no Debian 13, a mesma linha mostra só ValueError: too many values to unpack (expected 2). O erro é o mesmo; a mensagem é que ficou mais completa.

Faltaram valores: not enough values to unpack
dia, mes, ano = (12, 3)
$ python3 d_poucos.py
Traceback (most recent call last):
  File "/home/ana/d_poucos.py", line 1, in <module>
    dia, mes, ano = (12, 3)
    ^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 3, got 2)

"Valores insuficientes para desempacotar (esperava 3, recebeu 2)". Três lugares, duas coisas: o ano ficaria vazio. Como consertar: confira de onde vem a tupla; se o número de valores pode variar, use o asterisco: dia, *resto = ….

Dois asteriscos
notas = (8, 10, 6, 10, 9)
*a, *b = notas
$ python3 d_duas_estrelas.py
  File "/home/ana/d_duas_estrelas.py", line 2
    *a, *b = notas
    ^^^^^^
SyntaxError: multiple starred expressions in assignment

"Várias expressões com asterisco na atribuição". Com dois asteriscos, o Python não teria como decidir quantos valores vão para cada um. Repare que não aparece Traceback: um SyntaxError (erro de escrita) é encontrado antes de o programa começar a rodar. Como consertar: só um asterisco por desempacotamento.

Um asterisco sozinho
*todos = [1, 2, 3]
$ python3 d_estrela_so.py
  File "/home/ana/d_estrela_so.py", line 1
    *todos = [1, 2, 3]
    ^^^^^^
SyntaxError: starred assignment target must be in a list or tuple

"O alvo com asterisco precisa estar numa lista ou tupla". O asterisco quer dizer "o resto", e só existe resto se houver mais alguém. Como consertar: se você quer todos os itens numa lista, não precisa de asterisco: todos = list([1, 2, 3]). (Funcionaria *todos, = [1, 2, 3], com uma vírgula, mas ninguém escreve assim.)

Desempacotar um número
total = 30
a, b = total
$ python3 d_int.py
Traceback (most recent call last):
  File "/home/ana/d_int.py", line 2, in <module>
    a, b = total
    ^^^^
TypeError: cannot unpack non-iterable int object

"Não é possível desempacotar um objeto int, que não é iterável". Iterável é tudo o que tem itens para percorrer (tupla, lista, texto). Um número é um valor só; não há o que tirar da "mala". Como consertar: confira se a variável à direita é mesmo a tupla que você imagina (print(type(total))).

Missão: a fila da padaria tem quatro pessoas, e o programa dá ValueError: too many values to unpack. Conserte a linha 2 para que primeira fique com a Ana e esperando com a lista dos outros três.

fila = ["Ana", "Bia", "Caio", "Davi"]
primeira, esperando = fila
print("Primeira:", primeira)
print("Esperando:", esperando)
fila = ["Ana", "Bia", "Caio", "Davi"]
primeira, *esperando = fila
print("Primeira:", primeira)
print("Esperando:", esperando)

Referência rápida

EscritaO que faz
a, b = (1, 2)Desempacota: a = 1, b = 2
a, b = 1, 2O mesmo, com a tupla sem parênteses
a, b = b, aTroca os valores de a e b
primeiro, *resto = seqPrimeiro item e o resto numa lista
*inicio, ultimo = seqÚltimo item e o que vem antes numa lista
nome, _, cidade = registro_ marca o valor que você vai ignorar
for nome, nota in turma:Desempacota cada tupla da lista, a cada volta
print(*seq)Espalha os itens como valores separados na chamada
MensagemCausa provável
ValueError: too many values to unpack (expected 2, got 3)Mais valores do que variáveis
ValueError: not enough values to unpack (expected 3, got 2)Menos valores do que variáveis
SyntaxError: multiple starred expressions in assignmentMais de um * no lado esquerdo
SyntaxError: starred assignment target must be in a list or tupleUm *nome sozinho à esquerda do =
TypeError: cannot unpack non-iterable int objectTentou desempacotar um valor só (um número)

Exercícios

1. A coordenada

Complete para tirar os dois valores de padaria = (-5.0892, -42.8019):

latitude, = padaria

2. A troca

Complete a troca de x e y:

x, y =

3. O resto

Complete o símbolo para que outros recolha todos os itens depois do primeiro:

primeiro, outros = ["pão", "leite", "café"]

4. Depois de a, *b = (1, 2, 3), o que vale b?

5. nome, idade = ("Ana", 34, "Teresina") dá qual erro?

6. Por que a = b seguido de b = a não troca os valores?

Missão final: a conta da padaria

Missão: cada compra é uma tupla com o nome, o preço e a quantidade. Mude o for para desempacotar cada tupla em nome, preco, quantidade e mostre, para cada uma, uma linha como pão: R$ 5.00 (o preço vezes a quantidade, com duas casas: {preco * quantidade:.2f}).

compras = [("pão", 0.50, 10), ("leite", 4.75, 2), ("café", 18.90, 1)]
for item in compras:
    print(item)
compras = [("pão", 0.50, 10), ("leite", 4.75, 2), ("café", 18.90, 1)]
for nome, preco, quantidade in compras:
    print(f"{nome}: R$ {preco * quantidade:.2f}")

No lab, a solução mostra pão: R$ 5.00, leite: R$ 9.50 e café: R$ 18.90.


Resumo

  • Desempacotar é tirar os valores de uma sequência para várias variáveis de uma vez: dia, mes, ano = data.
  • Funciona com tupla, lista, texto, e com a tupla sem parênteses 1, 2.
  • a, b = b, a troca dois valores: o lado direito é calculado inteiro antes.
  • O *nome recolhe "o resto" numa lista (pode ficar vazia). Só um asterisco por vez.
  • _ é o nome costumeiro para um valor que você vai ignorar.
  • for nome, nota in turma: desempacota cada tupla da lista.
  • Variáveis e valores precisam bater: senão, too many values to unpack ou not enough values to unpack, com (expected X, got Y).