Pular para o conteúdo
Editor

Desempacotamento em Python: asterisco, troca e desestruturação

Intermediário20 min5 exercícios70 XP

Este tutorial foi traduzido do original em inglês.Read in EnglishLeer en españolЧитать на русскомอ่านภาษาไทยAvisar sobre um erro de tradução

0/5 exercícios

Imagine que você comprou pela internet um pacote com três itens: um livro, um fone de ouvido e uma capinha de celular. Quando a caixa chega, você abre e coloca cada item no seu lugar. O livro vai para a estante, o fone vai para a mesa e a capinha vai para o celular.

O desempacotamento em Python funciona do mesmo jeito. Você pega uma coleção de valores (uma tupla, uma lista ou qualquer iterável) e atribui cada valor à sua própria variável em uma única linha limpa. Não é preciso acessar os itens um por um com índices.

Neste tutorial, você vai aprender o desempacotamento básico, o truque elegante para trocar variáveis, as expressões com asterisco que capturam vários itens, o desempacotamento dentro de laços e como desestruturar dados aninhados.

Como funciona o desempacotamento básico?

Quando você tem uma tupla ou uma lista com vários valores, pode atribuir cada valor a uma variável separada em uma linha. O número de variáveis à esquerda precisa ser igual ao número de itens à direita.

Desempacotamento básico de tuplas e listas
# Unpacking a tuple
coordinates = (10, 20, 30)
x, y, z = coordinates
print(x) # 10
print(y) # 20
print(z) # 30
# Unpacking a list
colors = ['red', 'green', 'blue']
first, second, third = colors
print(first) # red
print(second) # green
print(third) # blue
Saída
10
20
30
red
green
blue

Sem desempacotamento, você precisaria acessar cada item pelo índice. O desempacotamento deixa o código mais curto e muito mais legível.

Sem desempacotamento (verboso)
point = (10, 20, 30)
x = point[0]
y = point[1]
z = point[2]
print(x, y, z)
Com desempacotamento (limpo)
point = (10, 20, 30)
x, y, z = point
print(x, y, z)

Você também pode desempacotar direto na atribuição, sem criar uma tupla com nome antes. O Python cria a tupla automaticamente quando você separa valores com vírgulas.

Desempacotamento sem parênteses
# Direct unpacking (no parentheses needed)
name, age, city = 'Alice', 25, 'Paris'
print(name) # Alice
print(age) # 25
print(city) # Paris
# This works because Python sees commas and creates a tuple
print(type(('Alice', 25, 'Paris'))) # <class 'tuple'>
Saída
Alice
25
Paris
<class 'tuple'>

Como trocar variáveis em uma linha

Na maioria das linguagens de programação, trocar o valor de duas variáveis exige uma variável temporária. O desempacotamento do Python torna isso desnecessário. Você pode trocar os valores em uma única linha elegante.

Trocando duas variáveis
a = 'hello'
b = 'world'
# Swap in one line!
a, b = b, a
print(a) # world
print(b) # hello
Saída
world
hello

Isso funciona porque o Python avalia primeiro o lado direito, empacotando os valores em uma tupla (b, a), e depois os desempacota em a, b. Tudo acontece com segurança em um único passo.

Outras linguagens (precisam de variável temporária)
a = 1
b = 2
temp = a
a = b
b = temp
print(a, b)  # 2 1
Python (uma linha)
a = 1
b = 2
a, b = b, a
print(a, b)  # 2 1

Você pode trocar três ou mais variáveis do mesmo jeito. O Python resolve tudo em um único passo.

Fazendo uma rotação entre três variáveis
# Rotate three variables
a, b, c = 1, 2, 3
print(f'Before: a={a}, b={b}, c={c}')
a, b, c = b, c, a
print(f'After: a={a}, b={b}, c={c}')
Saída
Before: a=1, b=2, c=3
After:  a=2, b=3, c=1

O que são expressões com asterisco (*rest)?

Às vezes você não sabe exatamente quantos itens uma coleção tem, ou só se importa com alguns itens específicos. A expressão com asterisco (*variable) captura os itens que sobram em uma lista.

Expressões com asterisco capturam os itens que sobram
# Capture the first item and everything else
numbers = [1, 2, 3, 4, 5]
first, *rest = numbers
print(first) # 1
print(rest) # [2, 3, 4, 5]
# Capture the last item and everything before it
*beginning, last = numbers
print(beginning) # [1, 2, 3, 4]
print(last) # 5
Saída
1
[2, 3, 4, 5]
[1, 2, 3, 4]
5

Você também pode colocar o asterisco no meio. Isso é ótimo quando você conhece o primeiro e o último item, mas quer ignorar tudo o que está entre eles.

Asterisco no meio
scores = [95, 80, 75, 90, 85, 70, 88]
# Get the first, last, and everything in between
first, *middle, last = scores
print(f'First: {first}') # 95
print(f'Middle: {middle}') # [80, 75, 90, 85, 70]
print(f'Last: {last}') # 88
Saída
First: 95
Middle: [80, 75, 90, 85, 70]
Last: 88
Asterisco com zero itens e com strings
# Star captures zero items (still a list)
a, b, *rest = [10, 20]
print(a) # 10
print(b) # 20
print(rest) # []
# Star from a string
first, *middle, last = 'Hello'
print(first) # H
print(middle) # ['e', 'l', 'l']
print(last) # o
Saída
10
20
[]
H
['e', 'l', 'l']
o

Como usar desempacotamento em laços for

O desempacotamento brilha dentro de laços for. Quando você percorre uma lista de tuplas (ou de listas), pode desempacotar cada item direto em variáveis com nome, em vez de acessá-las pelo índice.

Desempacotando tuplas em um laço for
# List of (name, age) tuples
students = [
('Alice', 16),
('Bob', 15),
('Charlie', 17),
]
# Unpack each tuple in the loop
for name, age in students:
print(f'{name} is {age} years old')
Saída
Alice is 16 years old
Bob is 15 years old
Charlie is 17 years old

Esse padrão é usado o tempo todo com enumerate() e dict.items(). Os dois retornam tuplas, e o desempacotamento deixa o código muito mais limpo.

Desempacotando com enumerate() e dict.items()
# enumerate() returns (index, value) tuples
fruits = ['apple', 'banana', 'cherry']
for i, fruit in enumerate(fruits):
print(f'{i}: {fruit}')
print()
# dict.items() returns (key, value) tuples
ages = {'Alice': 16, 'Bob': 15, 'Charlie': 17}
for name, age in ages.items():
print(f'{name} -> {age}')
Saída
0: apple
1: banana
2: cherry

Alice -> 16
Bob -> 15
Charlie -> 17

Como desempacotar estruturas de dados aninhadas

O desempacotamento em Python pode descer vários níveis. Se um valor dentro da sua coleção também for uma tupla ou uma lista, você pode desempacotá-lo usando parênteses aninhados no lado esquerdo.

Desempacotamento aninhado com parênteses
# A tuple containing a nested tuple
record = ('Alice', (95, 87, 92))
# Nested unpacking
name, (score1, score2, score3) = record
print(f'{name}: {score1}, {score2}, {score3}')
Saída
Alice: 95, 87, 92

Isso funciona em qualquer profundidade. Você pode até combinar o desempacotamento aninhado com uma expressão com asterisco: name, (first, *others) = ('Alice', (95, 87, 92)) coloca 95 em first e [87, 92] em others.

Desempacotamento aninhado em laços
# List of students with (name, (math, science, english))
students = [
('Alice', (95, 87, 92)),
('Bob', (78, 85, 90)),
('Charlie', (88, 92, 76)),
]
for name, (math, science, english) in students:
avg = (math + science + english) / 3
print(f'{name}: average = {avg:.1f}')
Saída
Alice: average = 91.3
Bob: average = 84.3
Charlie: average = 85.3

Erros comuns de desempacotamento para evitar

O desempacotamento fica intuitivo quando você pega o jeito, mas existem algumas armadilhas que pegam os iniciantes.

Erros comuns de desempacotamento
# Mistake 1: Forgetting parentheses in nested unpacking
# Wrong: name, x, y = ('Alice', (10, 20)) -> ValueError!
# Right:
name, (x, y) = ('Alice', (10, 20))
print(name, x, y)
# Mistake 2: Unpacking a single-item tuple
# You need the comma to make it a tuple!
value, = (42,) # Note the comma after 42
print(value) # 42
# Mistake 3: Forgetting that * always creates a list
first, *rest = 'AB'
print(type(rest)) # <class 'list'>, not str!
Saída
Alice 10 20
42
<class 'list'>

Exercícios práticos

Desempacote uma coordenada
Escreva o código

Desempacote a tupla point em três variáveis: x, y e z. Depois exiba as três em uma linha, separadas por espaços, usando print(x, y, z).

point = (7, 14, 21)
# Unpack into x, y, z and print them
Troque duas variáveis
Escreva o código

As variáveis first e second estão com os valores trocados. Inverta os valores usando a sintaxe de desempacotamento do Python (uma linha, sem variável temporária) e depois exiba as duas.

first = 'goodbye'
second = 'hello'
# Swap first and second in one line
print(first)
print(second)
Cabeça e cauda com asterisco
Escreva o código

Use uma expressão com asterisco para desempacotar a lista numbers em head (o primeiro item) e tail (todo o resto). Exiba os dois em linhas separadas.

numbers = [10, 20, 30, 40, 50]
# Unpack into head and tail using *
Preveja a saída do desempacotamento
Preveja a saída

O que este código exibe? Pense no que o asterisco captura e em qual tipo ele vira.

a, *b, c = [1, 2, 3, 4, 5, 6]
print(a)
print(b)
print(c)

Escreva três instruções print() que produzam exatamente a mesma saída.

# Predict the output and write the matching print statements
print("?")
print("?")
print("?")
Desempacote registros de alunos
Escreva o código

Você tem uma lista de registros de alunos. Cada registro é uma tupla (name, (math_score, english_score)). Use desempacotamento aninhado em um laço for para calcular e exibir a média de cada aluno.

Exiba cada linha no formato Name: average, em que a média é arredondada para 1 casa decimal com :.1f.

students = [
('Alice', (90, 80)),
('Bob', (70, 90)),
('Charlie', (85, 95)),
]
# Loop with nested unpacking and print averages

Tutoriais relacionados

Este tutorial foi útil?