Tuplas
Nesta aula, exploramos as tuplas em Python, estruturas de dados imutáveis e ordenadas. Aprendemos sobre imutabilidade, empacotamento e desempacotamento, quando usá-las e uma introdução às named tuples. O conteúdo inclui exemplos práticos e exercícios para fixação.
As tuplas são uma das estruturas de dados fundamentais em Python. Elas são semelhantes às listas, mas com uma diferença crucial: são imutáveis, ou seja, não podem ser alteradas após a criação. Isso as torna ideais para armazenar dados que não devem ser modificados, como coordenadas, configurações ou registros fixos.
Nesta aula, vamos explorar a imutabilidade, técnicas de empacotamento e desempacotamento, situações ideais para uso de tuplas e uma visão geral das named tuples, que combinam a imutabilidade das tuplas com a legibilidade dos dicionários.
Imutabilidade
Imutabilidade significa que, uma vez criada, uma tupla não pode ter seus elementos alterados, adicionados ou removidos. Isso é diferente das listas, que são mutáveis. A imutabilidade traz vantagens como segurança (garantia de que os dados não mudam inesperadamente) e eficiência (tuplas podem ser usadas como chaves de dicionários).
Exemplo de criação e tentativa de modificação:
# Criando uma tupla
coordenadas = (10, 20)
print(coordenadas[0]) # 10
# Tentando alterar um elemento (isso gera erro)
# coordenadas[0] = 15 # TypeError: 'tuple' object does not support item assignment
# Tentando adicionar um elemento
# coordenadas.append(30) # AttributeError: 'tuple' object has no attribute 'append'
Note que, embora a tupla em si seja imutável, se ela contiver objetos mutáveis (como listas), esses objetos ainda podem ser modificados. Por exemplo:
tupla_com_lista = ([1, 2], 3)
tupla_com_lista[0].append(3) # Isso é permitido, pois a lista é mutável
print(tupla_com_lista) # ([1, 2, 3], 3)
Isso é um ponto importante: a imutabilidade da tupla se refere à identidade dos elementos (as referências), não ao conteúdo dos objetos referenciados.
Empacotamento e desempacotamento
Empacotamento é o ato de criar uma tupla a partir de valores separados por vírgulas. Desempacotamento é o inverso: atribuir os elementos de uma tupla a variáveis individuais. Essas operações são muito utilizadas em Python para tornar o código mais legível e conciso.
Exemplo de empacotamento:
# Empacotamento
empacotado = 1, 2, 3
print(type(empacotado)) #
print(empacotado) # (1, 2, 3)
Exemplo de desempacotamento:
# Desempacotamento
a, b, c = empacotado
print(a, b, c) # 1 2 3
O desempacotamento é muito usado em loops e atribuições múltiplas. Por exemplo:
# Atribuição múltipla com tuplas
x, y = 10, 20
print(x, y) # 10 20
# Trocando valores de forma elegante
x, y = y, x
print(x, y) # 20 10
Também é possível usar o operador * para desempacotar parte da tupla:
# Desempacotamento com *
primeiro, *resto = (1, 2, 3, 4)
print(primeiro) # 1
print(resto) # [2, 3, 4]
Quando usar
Tuplas são recomendadas em situações onde os dados não devem ser modificados, como coordenadas, datas, configurações fixas, ou para representar registros simples. Elas são mais leves que listas e podem ser usadas como chaves em dicionários, ao contrário das listas.
Exemplos de uso comum:
- Retorno de múltiplos valores em funções:
return x, yretorna uma tupla. - Armazenar dias da semana, meses ou outras constantes.
- Chaves de dicionários:
dicionario = {(1, 2): 'ponto'} - Desempacotamento em loops:
for chave, valor in dicionario.items():
Comparação com listas: use tuplas quando a imutabilidade for desejada ou quando você quiser garantir que os dados não serão alterados. Use listas quando precisar modificar a coleção frequentemente.
Named tuples (visão geral)
As named tuples são uma extensão das tuplas, disponíveis no módulo collections. Elas permitem que você crie tuplas com campos nomeados, combinando a imutabilidade das tuplas com a legibilidade dos dicionários. Cada instância de uma named tuple tem atributos acessíveis por nome, além do acesso por índice.
Exemplo de criação e uso:
from collections import namedtuple
# Definindo uma named tuple 'Ponto' com campos x e y
Ponto = namedtuple('Ponto', ['x', 'y'])
# Criando uma instância
p1 = Ponto(10, 20)
print(p1.x) # 10
print(p1.y) # 20
print(p1[0]) # 10 (acesso por índice ainda funciona)
# Imutabilidade mantida
# p1.x = 30 # AttributeError: can't set attribute
Named tuples são úteis para representar registros simples, como coordenadas, dados de um banco de dados ou resultados de consultas, pois tornam o código mais legível e auto-documentado.
Boas práticas
Algumas boas práticas ao trabalhar com tuplas:
- Use tuplas para dados heterogêneos (diferentes tipos) que são fixos.
- Preferir
tuplealistquando a imutabilidade for desejada. - Evite tuplas com muitos elementos; considere usar uma named tuple ou uma classe para maior clareza.
- Ao desempacotar, use nomes de variáveis significativos para melhor legibilidade.
Referências
- Documentação oficial: Tuplas e sequências
- Tipos de dados embutidos: tupla
- Collections: namedtuple
- Real Python: Python Tuples
- W3Schools: Python Tuples
Exercícios
-
Crie uma tupla chamada
corescontendo três strings: "vermelho", "verde" e "azul". Em seguida, tente alterar o primeiro elemento para "amarelo" e veja o erro. Explique por que ocorre o erro.✓ Resposta:cores = ("vermelho", "verde", "azul") # cores[0] = "amarelo" # TypeError: 'tuple' object does not support item assignmentO erro ocorre porque tuplas são imutáveis: não é possível alterar seus elementos após a criação.
-
Dada a tupla
valores = (10, 20, 30, 40, 50), use desempacotamento para atribuir os dois primeiros valores às variáveisaeb, e o restante a uma listac. Imprima os resultados.✓ Resposta:valores = (10, 20, 30, 40, 50) a, b, *c = valores print(a) # 10 print(b) # 20 print(c) # [30, 40, 50] -
Crie uma função
dividirque receba dois números e retorne uma tupla com o quociente e o resto da divisão inteira. Teste com 10 e 3.✓ Resposta:def dividir(a, b): return a // b, a % b quociente, resto = dividir(10, 3) print(quociente, resto) # 3 1 -
Use uma named tuple para representar um ponto 3D com campos x, y, z. Crie um ponto (1, 2, 3) e acesse o valor de y pelo nome e pelo índice.
✓ Resposta:from collections import namedtuple Ponto3D = namedtuple('Ponto3D', ['x', 'y', 'z']) p = Ponto3D(1, 2, 3) print(p.y) # 2 print(p[1]) # 2 -
Explique por que tuplas podem ser usadas como chaves em dicionários, mas listas não. Dê um exemplo.
✓ Resposta:Dicionários exigem que as chaves sejam hasháveis. Tuplas são imutáveis, portanto hasháveis, enquanto listas são mutáveis e não podem ser hashadas. Exemplo:
d = {} d[(1, 2)] = "ponto" # Funciona # d[[1, 2]] = "ponto" # TypeError: unhashable type: 'list'