Desempacotamento de tupla

Tuple unpacking, ou em bom português, desempacotamento de tupla. Tá aí algo que usamos pra caramba, mas sobre o qual pouco ouvimos falar. Desempacotar uma tupla pode ser explicado como o ato de atribuir os elementos dela individualmente a outros objetos. Veja um exemplo de desempacotamento de tupla:

>>> t = (1, 2, 3, 4)
>>> a, b, c, d = t  # "desempacotando" uma tupla
>>> print b * c
6

No exemplo acima, o primeiro elemento da tupla t é atribuído para o nome a. O segundo elemento de t é atribuído para b, e assim por diante. É óbvio que, para desempacotar uma tupla, é necessário que tenhamos no lado esquerdo da expressão a quantidade necessária de variáveis para receber os valores. Veja uma situação que gera um erro por tentarmos desempacotar uma tupla de 4 elementos para 3 variáveis:

>>> t = (1, 2, 3, 4)
>>> a, b, c = t
Traceback (most recent call last):
  File "", line 1, in
ValueError: too many values to unpack

"ValueError: too many values to unpack", que significa “valores demais para desempacotar".

Mas isso é útil para quê?

Já viu uma função retornando mais de um valor em um único return em Python?

def f(x):
    return x, x*2, x*3

valor, dobro, triplo = f(2)

Isso é algo bastante comum em código Python. O código da segunda linha (return x, x*2, x*3) na realidade retorna apenas um valor, que é uma tupla. A expressão x, x*2, x*3 cria uma tupla de 3 elementos, apesar de não estar envolta em parênteses. Assim sendo, a chamada de função f(2) retorna uma tupla de 3 valores, que são então desempacotados para as variáveis valor, dobro e triplo, respectivamente.

Percorrendo listas de tuplas

Quando temos uma lista contendo tuplas, podemos percorrê-la assim como qualquer outra lista. Veja:

>>> lista = [(1, 2, 3), (2, 4, 6), (4, 8, 12), (8, 16, 24)]
>>> for tupla in lista:
...     print tupla
...
(1, 2, 3)
(2, 4, 6)
(4, 8, 12)
(8, 16, 24)

Dentro do for, poderíamos desempacotar os valores de cada tupla, se precisássemos usá-los individualmente:

>>> lista = [(1, 2, 3), (2, 4, 6), (4, 8, 12), (8, 16, 24)]
>>> for tupla in lista:
...     a, b, c = tupla
...     print a * b * c
...
6
48
384
3072

Mas, poderíamos fazer melhor, desempacotando os elementos dentro da expressão do for:

>>> lista = [(1, 2, 3), (2, 4, 6), (4, 8, 12), (8, 16, 24)]
>>> for (a, b, c) in lista:
...     print a * b * c
...
6
48
384
3072

Poderíamos também omitir os parênteses na hora de desempacotar as tuplas:

>>> lista = [(1, 2, 3), (2, 4, 6), (4, 8, 12), (8, 16, 24)]
>>> for a, b, c in lista:
...     print a * b * c
...
6
48
384
3072

Mas nem tudo interessa

Considere que nas tuplas da lista lista acima, somente nos interessa o primeiro elemento de cada tupla. Para não precisar criar dois novos nomes (b e c) que nunca serão usados, podemos utilizar um idioma que é um tanto comum em código python: usar o caractere de undescore _ como o nome da variável que vai receber o primeiro e último valores das tuplas:

>>> lista = [(1, 2, 3), (2, 4, 6), (4, 8, 12), (8, 16, 24)]
>>> for a, _, _ in lista:
...     print a * 2
...
2
4
8
16

Lembre-se: usamos isso somente em casos em que os elementos não serão necessários no escopo do for.

O _ é utilizado comumente como um nome para não me interessa. Por exemplo*, em uma tupla contendo nome, sobrenome e apelido, em um momento em que estamos interessados apenas no nome e no sobrenome, poderíamos usar o _ para indicar que o apelido não é importante neste momento:

dados_pessoais = ('Joao', 'Silva', 'joaozinho')
...
nome, sobrenome, _ = dados_pessoais

*Exemplo adaptado dessa resposta no StackOverflow.com

Como o autor da resposta no link acima comenta, é preciso tomar cuidado com o uso do _, pois ele também é utilizado em outros contextos e isso pode gerar confusão e mau-funcionamento. Ele é bastante usado com a biblioteca de internacionalização gettext como um atalho para funções usadas com muita frequência.

Então é isso. O desempacotamento de tuplas é um dos recursos que eu considero mais legais em Python, pois elimina bastante código desnecessário. Até a próxima! 🙂

Anúncios

3 comentários sobre “Desempacotamento de tupla

  1. Pingback: Função zip em Python | Python Help

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s