Desempacotamento e Empacotamento - Python
Desempacotamento
O desempacotamento (também chamado de desestruturação) refere-se à divisão de uma coleção (como tupla, lista, etc.) em valores separados.
Assim como muitas outras linguagens de programação, o Python oferece suporte à atribuição múltipla. Por exemplo:
x, y = 1, 2
print(x) # 1
print(y) # 2
Neste exemplo, os valores são atribuídos a duas variáveis de uma vez. A atribuição é feita com base na posição: a variável x
y
Esse exemplo já representa uma forma de desestruturação ou desempacotamento. Os valores 1 e 2, na verdade, formam uma tupla, pois a presença de vírgulas entre os valores caracteriza uma tupla. Poderíamos também ter escrito assim:
x, y = (1, 2)
print(x) # 1
print(y) # 2
Em qualquer caso, trata-se de desestruturação, onde o primeiro elemento da tupla é atribuído à primeira variável, o segundo elemento à segunda variável, e assim por diante. A divisão ocorre com base na posição.
Da mesma forma, podemos desempacotar outras tuplas, por exemplo:
name, age, company = ("Tom", 38, "Google")
print(name) # Tom
print(age) # 38
print(company) # Google
Não estamos limitados apenas a tuplas, pois também podemos desempacotar outras coleções, como listas:
people = ["Tom", "Bob", "Sam"]
first, second, third = people
print(first) # Tom
print(second) # Bob
print(third) # Sam
Ao desempacotar um dicionário, as variáveis recebem as chaves do dicionário:
dictionary = {"red": "vermelho", "blue": "azul", "green": "verde"}
r, b, g = dictionary
print(r) # red
print(b) # blue
print(g) # green
# obtendo o valor por chave
print(dictionary[g]) # verde
Desestruturação em laços
Em laços for
people = [
("Tom", 38, "Google"),
("Bob", 42, "Microsoft"),
("Sam", 29, "JetBrains")
]
for name, age, company in people:
print(f"Name: {name}, Age: {age}, Company: {company}")
Neste caso, percorremos uma lista de tuplas people
name
age
company
Outro exemplo é a função enumerate()
people = ["Tom", "Bob", "Sam"]
for index, name in enumerate(people):
print(f"{index}.{name}")
# resultado:
# 0.Tom
# 1.Bob
# 2.Sam
Ignorando valores
Se um elemento da coleção não for necessário, uma boa prática é usar um sublinhado (_
person = ("Tom", 38, "Google")
name, _, company = person
print(name) # Tom
print(company) # Google
Aqui, o segundo elemento da tupla é ignorado. Contudo, _
name
company
name, _, company = person
print(_) # 38
Empacotamento de valores e operador *
O operador *
num1 = 1
num2 = 2
num3 = 3
*numbers, = num1, num2, num3
print(numbers) # [1, 2, 3]
Aqui, empacotamos os valores da tupla (num1, num2, num3)
numbers
O empacotamento é útil para reunir os valores restantes após a atribuição dos resultados de uma desestruturação. Por exemplo:
head, *tail = [1, 2, 3, 4, 5]
print(head) # 1
print(tail) # [2, 3, 4, 5]
Neste caso, head recebe o primeiro elemento da lista e tail
Podemos obter todos os elementos, exceto o último:
*head, tail = [1, 2, 3, 4, 5]
print(head) # [1, 2, 3, 4]
print(tail) # 5
Ou elementos do meio, exceto o primeiro e o último:
head, *middle, tail = [1, 2, 3, 4, 5]
print(head) # 1
print(middle) # [2, 3, 4]
print(tail) # 5
Ou todos os elementos, exceto os dois primeiros:
first, second, *other = [1, 2, 3, 4, 5]
print(first) # 1
print(second) # 2
print(other) # [3, 4, 5]
Com isso, podemos obter diferentes combinações de elementos em uma coleção. Isso se aplica não apenas a listas, mas também a tuplas, dicionários e outras coleções.
Um exemplo interessante é obter apenas o primeiro, terceiro e último elementos, ignorando os demais:
first, _, third, *_, last = [1, 2, 3, 4, 5, 6, 7, 8]
print(first) # 1
print(third) # 3
print(last) # 8
Também podemos obter as chaves de um dicionário:
red, *other, green = {"red": "vermelho", "blue": "azul", "yellow": "amarelo", "green": "verde"}
print(red) # red
print(green) # green
print(other) # ['blue', 'yellow']
Desempacotamento com operadores * e **
Os operadores *
**
*
**
nums1 = [1, 2, 3]
nums2 = (4, 5, 6)
# desempacotando a lista nums1 e a tupla nums2
nums3 = [*nums1, *nums2]
print(nums3) # [1, 2, 3, 4, 5, 6]
Aqui, desempacotamos os valores da lista nums1
nums2
nums3
O mesmo princípio se aplica a dicionários, usando o operador **
dictionary1 = {"red": "vermelho", "blue": "azul"}
dictionary2 = {"green": "verde", "yellow": "amarelo"}
# desempacotando dicionários
dictionary3 = {**dictionary1, **dictionary2}
print(dictionary3) # {'red': 'vermelho', 'blue': 'azul', 'green': 'verde', 'yellow': 'amarelo'}