Tuplas#

Tuplas são outra estrutura de dados bem parecidas com listas, com uma diferença super importante e relevante. Vamos explorar essa estrutura ao longo deste capítulo.

Definição#

Tuplas também são uma sequência de elementos e possuem algumas características em comum com listas.

Dentre as características de listas, tuplas também possuem as seguintes:

  • Ordenadas: As listas mantêm a ordem dos elementos conforme são adicionados.

  • Permite duplicatas: Listas podem conter elementos duplicados. Cada elemento na lista mantém sua própria posição e pode ser acessado individualmente.

  • Heterogêneas: Uma lista pode conter elementos de diferentes tipos de dados. Por exemplo, você pode ter uma lista que contém números, strings e até mesmo outras listas.

A única característica diferentre entre tuplas e listas é que tuplas são imutáveis e listas são mutáveis.

Em palavras mais simples, usando listas eu consido modificar (alterar a ordem, inserir e remover) os seus elementos, enquanto que tuplas não tem essa flexibilidade, não sendo possível alterar a ordem, inserir, remover e nem modificar seus elementos uma vez criada a tupla.

Sintaxe básica#

Tuplas começam e terminam com parênteses ( ), e seus elementos são separados com vírgula (,) assim como nas listas.

tupla_de_numeros = (10, 50, 40, 65, 90, 70, 30, 156)
print(tupla_de_numeros)
(10, 50, 40, 65, 90, 70, 30, 156)

Como os parênteses ( ) existem também para priorizar operações matemática (lembra da tabela de precedência?) o único caso que pode ser um tanto quanto confuso é a criação de tuplas com um único elemento. Observem o caso abaixo.

tupla_de_um_elemento = (1)

Eu faço a seguinte pergunta, a variável tupla_de_um_elemento acima é uma tupla? Por incrível que pareça não é! Como podemos confirmar? Vamos checar essa informação usando a função type, conforme já aprendemos.

tupla_de_um_elemento = (1)
print(type(tupla_de_um_elemento))
<class 'int'>

O trecho de código acima confirma que a variável tupla_de_um_elemento não é uma tupla mas sim um inteiro, apesar da existência dos parênteses ( ).

Por que? Como tuplas são sequências, elas precisam da existência da vírgula , para separar os elementos, por mais que exista apenas um único elemento.

Portanto, uma tupla de um único elemento seria representada desta forma:

tupla_de_um_elemento = (1,)
print(type(tupla_de_um_elemento))
<class 'tuple'>

Dica (tipo do elemento)

O que mencionei acima sobre tuplas de um elemento é válido para qualquer tipo de dado dentro da tupla. Quer ver só? Qual seria o tipo de dado da variável abaixo? string ou tupla?

variavel = ("uma string qualquer")

Se você disse tupla, eu lhe pergunto, onde está a vírgula , separando os elementos? No final ela acaba sendo uma string!

Para transformarmos essa variável acima em tupla, precisamos adicionar a vírgula ao final.

variavel = ("uma string qualquer",)

Você pode conferir o que estou dizendo usando a função type da mesma forma que fiz nos exemplos acima.


Por mais que seja estranho o formato `(elemento,)`, esta é a forma que o Python usa para distinguir parenteses `( )` usados em tuplas e em operações matemáticas.

Operações em comum entre listas e tuplas#

Tuplas e listas são bem parecidas em vários aspectos, os quais não vou detalhar tanto aqui, considerando que você já os aprendeu no capítulo de listas.

Tanto listas quanto tuplas utilizam indexação começando em 0. Isso significa que o primeiro elemento está no índice 0, o segundo no índice 1, e assim por diante. A indexação permite acessar elementos individuais diretamente.

produto = (123, "camiseta", 29.99)
identificador = produto[0]
nome = produto[1]
preco = produto[2]

print(f"O produto {nome} tem o ID {identificador} e custa R${preco}")
O produto camiseta tem o ID 123 e custa R$29.99

O fatiamento com a sintaxe variavel[start:step:stop] que vimos em strings e lista funciona exatamente da mesma forma com tuplas.

Dado que tuplas também são sequências, podemos medir seu comprimento com a função len().

produto = (123, "camiseta", 29.99)
print(len(produto))
3

Qual a diferença entre listas e tuplas afinal de contas?#

Direto e reto: tuplas são imutáveis e listas são mutáveis.

Se você se recorda, ao longo do capítulo de listas, vimos que existem vários métodos de inserção (append, extend e insert), deleção (remove, pop e clear), ordenação (sort e reverse) e ainda podemos sobrescrever valores de uma lista.

Pois bem, uma vez que tuplas são imutáveis, não existem métodos que permitam tais modificações em tuplas. Tuplas, portanto, tem bem menos métodos e operações do que uma lista por conta desta característica. Os únicos métodos que existem em tuplas são index e count para fins de consulta. Observem abaixo:

lista = [1, 2, 3, 4]
tupla = (1, 2, 3, 4)

print("Métodos de lista")
print([metodo for metodo in dir(lista) if not metodo.startswith("__")])

print("\nMétodos de tuplas")
print([metodo for metodo in dir(tupla) if not metodo.startswith("__")])
Métodos de lista
['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Métodos de tuplas
['count', 'index']

Nota (código desconhecido)

No código do exemplo acima, você pode não ter visto ainda for, if, if not, for dentro de listas e nem a função dir. O objetivo do código acima não é demonstrar tais conceitos, mas sim mostrar quais são os métodos de listas e tuplas para fins comparativos.

Conforme você vai avançando no livro, você vai começar a se deparar cada vez mais com essa situação na qual «código que é novo para você», tipo o exemplo acima. Isso é bastante comum inclusive no mundo real. Foque no objetivo principal do tema que você está estudando e aprenda algo novo com o código desconhecido sem perder de vista o foco principal.

Uma dica pra você que gosta sempre de ir além: a função dir imprime na tela todos os métodos disponíveis de um objeto, incluindo alguns métodos especiais que começam com __. Estes são bem mais avançados, por isso eu os removi do print usando o filtro if not metodo.startswith("__"), deixando apenas os métodos não especiais.

Ah, mas se tuplas tem menos operações, então deve ser pior né? Vou sempre usar listas então!. Calma, não é bem por aí. Flexiblidade de listas é bom, mas nem sempre.

As vezes você de fato não quer mudar a quantidade de elementos na sua sequencia, ou que os elementos sejam alterados. Quer um exemplo prático?

meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
print(meses)
('jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez')

Você, no caso acima em uma sequencia de meses, iria em algum momento:

  • acrescentar ou remover algum mês?

  • trocar a ordem dos meses?

  • modificar um mês existente (não vale pensar em sacanear o coleguinha aqui hein!)?

Se a resposta para todas as perguntas for não, então não há porque você usar listas! E, aliás, usar tuplas neste caso é bem mais sensato porque sua sequência será imutável. Vejamos:

# Não é possível alterar nenhum mês
meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
meses[0] = "mes inexistente"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[9], line 3
      1 # Não é possível alterar nenhum mês
      2 meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
----> 3 meses[0] = "mes inexistente"

TypeError: 'tuple' object does not support item assignment
# Não temos nenhum método de inserção, deleção e ordenação
meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
meses.append("mes inexistente")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[10], line 3
      1 # Não temos nenhum método de inserção, deleção e ordenação
      2 meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
----> 3 meses.append("mes inexistente")

AttributeError: 'tuple' object has no attribute 'append'
meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
meses.sort()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[11], line 2
      1 meses = ("jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez")
----> 2 meses.sort()

AttributeError: 'tuple' object has no attribute 'sort'

Em resumo, a nossa sequência de meses está totalmente protegida de modificações indesejadas. E é exatamente isso que queremos!

Prática (desafio)#

Agora que você aprendeu a manipular listas e tuplas, eu criei um exercício desafio para você! Vamos realizar uma análise de vendas no exercício 9?

Conclusão#

Nestes 2 últimos capítulo, exploramos as listas e tuplas em Python, duas estruturas de dados fundamentais. São as duas principais estruturas básicas para trabalharmos com dados ordenados. As listas, com sua natureza mutável, oferecem flexibilidade para armazenar, modificar e gerenciar coleções de itens de forma dinâmica. Já as tuplas, com sua imutabilidade, garantem a integridade dos dados, tornando-se ideais para armazenar informações que não devem ser alteradas. Ambas desempenham papéis cruciais em diversas situações, desde a manipulação simples de dados até a construção de estruturas mais complexas. Espero que você tenha compreendido principalmente a diferença entre listas e tuplas e sobre quando e como usar cada uma delas.

No próximo capítulo vamos aprender sobre a primeira estrutura de dados não ordenada, os dicionários!