Escolhendo a estrutura certa
Esta aula ensina a escolher a estrutura de dados adequada em Python, comparando listas, tuplas, sets e dicionários sob os aspectos de características, complexidade de tempo, casos de uso e performance. O aluno aprenderá a tomar decisões informadas para escrever código mais eficiente e legível.
Em Python, a escolha da estrutura de dados correta pode impactar drasticamente a legibilidade, eficiência e performance do seu código. Cada estrutura — lista, tupla, set e dicionário — foi projetada para resolver um tipo específico de problema, e usá-las de forma inadequada pode levar a código lento ou confuso. Nesta aula, vamos analisar as principais diferenças entre elas, entender a complexidade de suas operações mais comuns e discutir casos de uso típicos. Ao final, você será capaz de selecionar a estrutura ideal para cada situação.
Lista vs tupla vs set vs dict
As quatro estruturas de dados fundamentais em Python são: list, tuple, set e dict. Cada uma possui características distintas em relação à mutabilidade, ordenação, unicidade e acesso a elementos.
Lista: mutável, ordenada, permite elementos duplicados. Ideal para coleções de itens que podem ser alterados e onde a ordem importa. Exemplo: lista de tarefas, histórico de ações.
Tupla: imutável, ordenada, permite duplicatas. Usada para dados que não devem ser modificados, como coordenadas (x, y) ou constantes. Também é mais eficiente que lista para iteração e consumo de memória.
Set: mutável, não ordenada (até Python 3.6, a ordem é arbitrária; a partir de 3.7, a ordem de inserção é preservada apenas na implementação CPython, mas não é garantida), não permite duplicatas. Excelente para operações de conjunto (união, interseção) e remoção de duplicatas.
Dict: mutável, ordenado (a partir de Python 3.7), mapeia chaves únicas a valores. Ideal para associações chave-valor, como um catálogo de produtos com IDs.
Complexidade
A complexidade de tempo (Big O) das operações comuns varia entre as estruturas. Conhecer esses valores ajuda a prever o desempenho do código.
- Lista: acesso por índice O(1); inserção/remoção no final O(1); inserção/remoção no início ou meio O(n); busca (in) O(n).
- Tupla: acesso O(1); busca O(n); não suporta inserção/remoção (imutável).
- Set: busca (in), inserção, remoção O(1) em média (hash table); iteração O(n).
- Dict: acesso, inserção, remoção por chave O(1) em média; iteração O(n).
Nota: A complexidade O(1) para sets e dicts depende de uma boa função hash e ausência de colisões. Em casos patológicos, pode degradar para O(n), mas isso é raro.
Casos de uso
A escolha correta depende do problema:
- Lista: quando você precisa de uma sequência ordenada que será modificada (adicionar/remover itens) ou quando precisa acessar elementos por índice. Exemplo: lista de alunos em uma turma.
- Tupla: quando você tem uma coleção fixa de itens que não deve ser alterada, como coordenadas geográficas ou parâmetros de configuração. Também usada como chave de dicionário (por ser imutável).
- Set: para remover duplicatas rapidamente ou realizar operações de conjunto (união, interseção, diferença). Exemplo: verificar se um item está em uma coleção grande com frequência.
- Dict: quando você precisa associar chaves a valores e fazer buscas rápidas por chave. Exemplo: armazenar contagens de palavras em um texto.
Performance
Para operações de busca e inserção, sets e dicts são significativamente mais rápidos que listas e tuplas quando o volume de dados é grande. Por exemplo, verificar se um elemento existe em uma lista de 1 milhão de itens leva O(n), enquanto em um set leva O(1). No entanto, sets e dicts consomem mais memória devido à tabela hash.
Tuplas são levemente mais rápidas que listas para iteração e acesso, e ocupam menos memória. Se você não precisa modificar a coleção, prefira tupla.
Exemplo prático de tempo de busca:
import time
# Criando uma lista e um set com 1 milhão de elementos
data_list = list(range(1_000_000))
data_set = set(data_list)
# Medindo tempo de busca na lista
start = time.time()
print(999_999 in data_list)
print("Lista:", time.time() - start)
# Medindo tempo de busca no set
start = time.time()
print(999_999 in data_set)
print("Set:", time.time() - start)
Resultado típico: a busca no set é centenas de vezes mais rápida.
Boas práticas
- Use tuplas para dados imutáveis e como chaves de dicionário.
- Use sets para eliminar duplicatas e testes de pertinência.
- Use dicts para mapeamentos chave-valor.
- Use listas quando a ordem e mutabilidade são necessárias.
- Evite usar listas para buscas frequentes; prefira sets ou dicts.
- Considere a memória: se a economia de memória for crítica, tuplas e listas são melhores que sets e dicts.
Referências
- Documentação oficial: Estruturas de dados
- Set types — set e frozenset
- Mapping types — dict
- Python Wiki: Complexidade de tempo
- Real Python: Lists vs Tuples
Exercícios
- Qual estrutura de dados você usaria para armazenar uma lista de números de telefone de clientes, onde cada número é único e a ordem não importa? Justifique.
- Escreva um código que remova elementos duplicados de uma lista usando um set e depois converta de volta para lista, mantendo a ordem original.
- Explique por que tuplas podem ser usadas como chaves de dicionário, mas listas não.
- Qual é a complexidade de tempo da operação
inem uma lista vs um set? Dê um exemplo onde a diferença é crítica. - Dado um dicionário com nomes de alunos e suas notas, escreva um código que retorne uma lista dos alunos que tiraram nota acima de 7. Use compreensão de dicionário ou lista.
def remove_duplicates_preserve_order(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
# Exemplo de uso
original = [3, 1, 2, 1, 3, 4]
print(remove_duplicates_preserve_order(original)) # [3, 1, 2, 4]
notas = {'Ana': 8.5, 'João': 6.0, 'Maria': 9.0, 'Pedro': 7.5}
alunos_acima_7 = [nome for nome, nota in notas.items() if nota > 7]
print(alunos_acima_7) # ['Ana', 'Maria', 'Pedro']