Tuplas em Python#


Objetivos de Aprendizagem#

  • Ser capaz de definir corretamente uma tupla em Python, incluindo a criação de tuplas vazias e com um único elemento (compreendendo a importância da vírgula).

  • Demonstrar compreensão do conceito de imutabilidade das tuplas e suas implicações.

  • Compreender a descompactação de valores de uma tupla em variáveis individuais para melhorar a legibilidade do código.

Conceitos Fundamentais#

Em sua essência, uma tupla é uma sequência de itens. Pense nela como uma coleção de valores agrupados juntos sob um único nome. A grande diferença entre tuplas e listas (que já vimos) reside em um aspecto crucial: imutabilidade. Tuplas são imutáveis, o que significa que você não pode modificar seus elementos após a criação.

Sintaxe: Tuplas são definidas usando parênteses () e os itens são separados por vírgulas.

tupla_vazia = () # Tupla vazia
print(tupla_vazia)
print(type(tupla_vazia))
()
<class 'tuple'>
minha_tupla = (1, "Olá", 3.14)  # Uma tupla com um inteiro, uma string e um float
print(minha_tupla)
print(type(minha_tupla))
(1, 'Olá', 3.14)
<class 'tuple'>

Cuidado ao criar uma tupla com apenas um elemento! Use uma vírgula no final para indicar explicitamente ao Python que você está criando uma tupla, mesmo que ela contenha apenas um valor:

tupla_unico_elemento = (5,) # Tupla com apenas um elemento - a vírgula é essencial!

print(tupla_unico_elemento)
print(type(tupla_unico_elemento))
(5,)
<class 'tuple'>

Sem a vírgula, Python interpretará a expressão como um valor simples entre parênteses, e não como uma tupla:

valor_simples = (5)
print(valor_simples),
print(type(valor_simples))
5
<class 'int'>

Operações Básicas#

Embora não possamos modificar o conteúdo de uma tupla, podemos realizar diversas operações:

Acesso aos Elementos: Assim como listas, acessamos elementos por índice (começando em 0):

minha_tupla = (1, "Olá", 3.14)
print(minha_tupla[0]) # primeiro_elemento será 1
print(minha_tupla[1])  # segundo_elemento será "Olá"
1
Olá

Slicing: Podemos extrair partes de uma tupla usando slicing.

minha_tupla = (1, 2, 3, 4, 5)
print(minha_tupla[1:4])  # sub_tupla será (2, 3, 4)
(2, 3, 4)

Concatenação: Podemos combinar duas ou mais tuplas usando o operador +.

tupla1 = (1, 2)
tupla2 = (3, 4)
tupla_concatenada = tupla1 + tupla2  # Cria uma nova tupla -> tupla_concatenada será (1, 2, 3, 4)
print(tupla_concatenada)
(1, 2, 3, 4)

Repetição: Podemos repetir uma tupla usando o operador *.

tupla = (1,)
tupla_repetida = tupla * 3  # tupla_repetida será (1, 2, 1, 2, 1, 2)
print(tupla_repetida)
(1, 1, 1)

Percorrendo um Tuplas em um Loop#

Vamos criar uma nova tupla e percorrê-la utilizando um loop for:

minha_tupla = (1, 2, 3, 4, 5, 6)

for x in minha_tupla:
    print(x)
1
2
3
4
5
6

Funções built-in do Python#

Exemplo 1: len() - Obtendo o tamanho da Tupla

A função len() retorna o número de elementos em uma tupla.

minha_tupla = (10, 20, 30, 40) 
print(f"O tamanho da tupla é: {len(minha_tupla)}")  # Saída: O tamanho da tupla é: 4
O tamanho da tupla é: 4

Exemplo 2: max() - Encontrando o Maior Elemento

A função max() retorna o maior elemento em uma tupla (considerando a ordem de comparação natural para os tipos de dados presentes).

numeros = (5, 12, 8, 20, 3)
maior_numero = max(numeros)
print(f"O maior número na tupla é: {maior_numero}")  # Saída: O maior número na tupla é: 20
O maior número na tupla é: 20

Exemplo 3: min() - Encontrando o Menor Elemento

Similar a max(), min() retorna o menor elemento da tupla.

temperaturas = (15, 28, 22, 18)
menor_temperatura = min(temperaturas)
maior_temperatura = max(temperaturas)
print(f"A menor temperatura na tupla é: {menor_temperatura}") 
print(f"A maior temperatura na tupla é: {maior_temperatura}")
A menor temperatura na tupla é: 15
A maior temperatura na tupla é: 28

Exemplo 4: sum() - Somando os Elementos (para Tuplas Numéricas)

A função sum() calcula a soma de todos os elementos numéricos em uma tupla.

valores = (1, 2, 3, 4, 5)
soma_total = sum(valores)
print(f"A soma dos valores na tupla é: {soma_total}")  # Saída: A soma dos valores na tupla é: 15
A soma dos valores na tupla é: 15

Exemplo 5: sorted() - Ordenando uma Tupla (sem modificar a original)

sorted() retorna uma nova lista contendo todos os itens da tupla em ordem crescente. A tupla original permanece inalterada, pois as tuplas são imutáveis.

desordenado = (3, 1, 4, 1, 5, 9, 2, 6)
ordenado = sorted(desordenado)  # Retorna uma lista ordenada
print(f"Tupla original: {desordenado}") # Saída: Tupla original: (3, 1, 4, 1, 5, 9, 2, 6)
print(f"Lista ordenada: {ordenado}")   # Saída: Lista ordenada: [1, 1, 2, 3, 4, 5, 6, 9]
Tupla original: (3, 1, 4, 1, 5, 9, 2, 6)
Lista ordenada: [1, 1, 2, 3, 4, 5, 6, 9]

Observações Importantes:

  • As funções max(), min() e sum() geralmente requerem que todos os elementos da tupla sejam do mesmo tipo (ou tipos comparáveis). Tentar usá-las com tipos incompatíveis resultará em um erro.

  • sorted() é extremamente útil para ordenar dados, mas lembrem-se de que ela retorna uma lista, não uma tupla. Se você precisar manter a estrutura de tupla, precisará converter a lista resultante de volta para uma tupla usando tuple().

Por Que Usar Tuplas? Casos de Uso Reais#

A imutabilidade das tuplas oferece vantagens importantes:

Segurança dos Dados: Garante que os dados não sejam alterados acidentalmente.

Eficiência: Tuplas são geralmente mais rápidas para acessar e iterar do que listas, pois o Python pode otimizar seu armazenamento.

%timeit minha_lista = [l for l in range(100000)]
1.09 ms ± 2.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit minha_tupla = (x for x in range(100000))
210 ns ± 3.51 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

Chaves de Dicionários: As tuplas podem ser usadas como chaves em dicionários (listas não podem!). Isso porque as chaves de dicionário precisam ser imutáveis.

# Dicionário onde as chaves são tuplas de coordenadas (x, y)
elementos_graficos = {
    (10, 20): "Botão",
    (50, 75): "Caixa de Texto",
    (120, 40): "Imagem",
    (80, 100): "Rótulo"
}
# Acessando um elemento gráfico pela sua coordenada
elemento_na_posicao = elementos_graficos[(50, 75)]
print(f"O elemento na posição (50, 75) é: {elemento_na_posicao}")  # Saída: O elemento na posição (50, 75) é: Caixa de Texto
O elemento na posição (50, 75) é: Caixa de Texto
# Adicionando um novo elemento gráfico em uma nova coordenada
elementos_graficos[(200, 150)] = "Barra de Progresso"
print(f"Dicionário atualizado: {elementos_graficos}")
Dicionário atualizado: {(10, 20): 'Botão', (50, 75): 'Caixa de Texto', (120, 40): 'Imagem', (80, 100): 'Rótulo', (200, 150): 'Barra de Progresso'}
# Verificando se uma coordenada existe no dicionário
if (30, 60) in elementos_graficos:
    print("A coordenada (30, 60) existe no dicionário.")
else:
    print("A coordenada (30, 60) não existe no dicionário.") # Esta linha será executada.
A coordenada (30, 60) não existe no dicionário.
# Iterando sobre o dicionário
for coordenadas, elemento in elementos_graficos.items():
    print(f"Na posição {coordenadas}, temos um(a) {elemento}")
Na posição (10, 20), temos um(a) Botão
Na posição (50, 75), temos um(a) Caixa de Texto
Na posição (120, 40), temos um(a) Imagem
Na posição (80, 100), temos um(a) Rótulo
Na posição (200, 150), temos um(a) Barra de Progresso

Retornando Múltiplos Valores de uma Função: É uma prática comum retornar múltiplos valores de uma função usando uma tupla.

def coordenadas():
    return 10, 20 # Retorna uma tupla (x, y)

ponto = coordenadas()
print(ponto)
print(type(ponto))
(10, 20)
<class 'tuple'>

Unpacking#

Vamos agora explorar uma técnica muito elegante e útil chamada “unpacking” (desempacotamento) com tuplas. Quando você tem uma tupla, pode atribuir seus elementos individualmente a variáveis em uma única linha. Isso é especialmente conveniente quando você sabe quantos elementos a tupla contém e quer dar nomes significativos a cada um deles.

Por exemplo, se você tiver uma tupla (x, y) representando coordenadas, pode descompactá-la diretamente em duas variáveis:

x, y = (10, 20) 
print(x)
print(y)
10
20

Isso torna o código mais legível e conciso, evitando a necessidade de acessar os elementos da tupla por índice.

Observação: O número de variáveis no lado esquerdo deve corresponder exatamente ao número de elementos na tupla; caso contrário, você receberá um erro.

Exercícios Teóricos#

  1. **Explique a diferença fundamental entre uma lista e uma tupla em Python, focando na característica de imutabilidade.

  2. O que significa “unpacking” de uma tupla? Dê um exemplo prático de como o unpacking pode ser útil e por que ele torna o código mais legível. (Considerem a atribuição de valores a variáveis).

  3. Por que as tuplas são frequentemente usadas para retornar múltiplos valores de uma função em Python? Qual a vantagem dessa abordagem em relação a retornar uma lista? (Pensem na clareza e segurança do código.)

  4. Em quais situações você escolheria usar uma tupla em vez de uma lista? Dê exemplos concretos de cenários onde a imutabilidade da tupla seria uma vantagem significativa. (Pensem em casos de uso práticos.)

  5. Considere o seguinte código Python:

    dados_pessoa = ("Alice", 30, "Engenheira")
    nome, idade, profissao = dados_pessoa
    
    print(f"Nome: {nome}")
    print(f"Idade: {idade}")
    print(f"Profissão: {profissao}")
    
    # Tentativa de modificar a tupla (comentada para evitar erro)
    # dados_pessoa[1] = 31  # Isso causaria um TypeError!
    

    Responda às seguintes perguntas:

    1. Qual é o valor impresso para “Nome”, “Idade” e “Profissão” após a execução do código? Explique como esses valores são atribuídos às variáveis.

    2. Por que a linha comentada dados_pessoa[1] = 31 causaria um erro se fosse “descomentada” e executada? Qual tipo de erro seria lançado?

    3. O que é “unpacking” no contexto deste código, e qual o benefício de usar essa técnica em vez de acessar os elementos da tupla individualmente (por exemplo, dados_pessoa[0], dados_pessoa[1], etc.)?

    4. Suponha que você quisesse criar uma nova tupla a partir de dados_pessoa e adicionar um novo elemento no início (por exemplo, o ID da pessoa). Como você faria isso sem modificar a tupla original?

    5. Em qual cenário prático você usaria uma tupla como dados_pessoa para representar informações sobre uma pessoa? Justifique sua resposta considerando as características das tuplas.

Exercícios para Praticar#

  1. Função para Inverter Tupla: Escreva uma função que receba uma tupla como entrada e retorne uma nova tupla com os elementos na ordem inversa.

  2. Encontrando o Segundo Maior Elemento: Crie uma função que receba uma tupla de números e encontre o segundo maior elemento.

  3. Tuplas como Chaves de Dicionário: Crie um dicionário onde as chaves são tuplas contendo o nome e a idade de algumas pessoas. Imprima o dicionário.


Conclusão#

Exploramos as tuplas, um tipo de dado fundamental em Python para armazenar coleções imutáveis de itens. Vimos como elas se diferenciam das listas, principalmente pela sua imutabilidade, o que garante a integridade dos dados e pode otimizar o desempenho em certas situações. Dominar tuplas é crucial para tarefas como retornar múltiplos valores de funções.

O que aprendemos hoje?#

  • Definimos e criamos tuplas.

  • Compreendemos a imutabilidade das tuplas e suas implicações.

  • Acessamos elementos de uma tupla por índice.

  • Exploramos o uso do operador unpacking para atribuir valores de uma tupla a variáveis individuais.

  • Vimos como as tuplas são mais eficientes em termos de desempenho que listas, especialmente quando não precisam ser modificadas.

Próximos Passos#

  • Prática: Resolva os exercícios propostos no material da aula para solidificar o entendimento dos conceitos.

  • Exploração: Pesquise sobre as aplicações de tuplas em áreas como programação funcional e representação de dados estruturados.