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

Exercícios

  1. 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.
  2. ✓ Resposta: Set. Como os números são únicos e a ordem não importa, o set garante unicidade automaticamente e oferece busca O(1) para verificar duplicatas.
  3. 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.
  4. ✓ Resposta:
    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]
  5. Explique por que tuplas podem ser usadas como chaves de dicionário, mas listas não.
  6. ✓ Resposta: Dicionários exigem que as chaves sejam hasháveis (imutáveis). Tuplas são imutáveis, portanto hasháveis. Listas são mutáveis, não podem ser hashadas, logo não podem ser usadas como chaves.
  7. Qual é a complexidade de tempo da operação in em uma lista vs um set? Dê um exemplo onde a diferença é crítica.
  8. ✓ Resposta: Lista: O(n); Set: O(1) em média. Exemplo crítico: verificar se um usuário está em uma lista de 10 milhões de IDs repetidamente em um loop. Usar lista tornaria o programa extremamente lento, enquanto set é instantâneo.
  9. 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.
  10. ✓ Resposta:
    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']