Comparação de Containers e Comprehensions Abrangentes
Cobrimos listas, tuplas, dicionários e conjuntos individualmente. Agora vamos fazer uma comparação lado a lado — quais são as diferenças, e quando você deve usar cada um? Também dominaremos completamente as comprehensions, um dos recursos mais poderosos do Python.
1. Quatro Containers Comparados
| Característica | Lista (list) |
Tupla (tuple) |
Dicionário (dict) |
Conjunto (set) |
|---|---|---|---|---|
| Sintaxe | [] |
() |
{chave: valor} |
{} ou set() |
| Ordenado | ✅ Sim | ✅ Sim | ✅ Ordem de inserção (3.7+) | ❌ Não ordenado |
| Mutável | ✅ | ❌ | ✅ | ✅ |
| Duplicatas | ✅ Permitidas | ✅ Permitidas | Chaves únicas, valores podem repetir | ❌ Elementos únicos |
| Acesso | Índice [0] |
Índice [0] |
Chave ["chave"] |
Sem suporte a índice |
| Velocidade de busca | O(n) lenta | O(n) lenta | O(1) muito rápida | O(1) muito rápida |
| Uso típico | Dados ordenados, coleções dinâmicas | Dados fixos, retornos de função | Mapeamentos, caches | Dedup, operações de conjunto |
Exemplo: Comparação de Seleção de Container (Dificuldade ⭐⭐)
# Mesmo cenário implementado com diferentes containers
# Cenário: armazenar nomes de alunos
# Lista — ordenada, fácil de adicionar/remover
students_list = ["Alice", "Bob", "Charlie"]
students_list.append("Diana")
print(f"Lista: {students_list[0]}") # Alice
# Tupla — fixa (como uma lista de chamada)
students_tuple = ("Alice", "Bob", "Charlie")
# students_tuple[0] = "xxx" # Erro! Tuplas são imutáveis
print(f"Tupla: {students_tuple[0]}") # Alice
# Dicionário — busca rápida por ID
students_dict = {
"001": "Alice",
"002": "Bob",
"003": "Charlie",
}
print(f"Dict: {students_dict['002']}") # Bob — velocidade O(1)
# Conjunto — deduplicação (como uma lista de presença)
attendance = {"Alice", "Bob", "Charlie", "Alice"}
print(f"Set: {attendance}") # {'Bob', 'Charlie', 'Alice'} — Alice deduplicada
2. List Comprehensions Avançadas
A Lição 11 cobriu comprehensions básicas. Vamos nos aprofundar.
Múltiplas Condições
numbers = range(1, 31)
# Divisível por 3 E por 5
filtered = [n for n in numbers if n % 3 == 0 and n % 5 == 0]
print(filtered) # [15, 30]
# Divisível por 3 OU por 5
filtered = [n for n in numbers if n % 3 == 0 or n % 5 == 0]
print(filtered) # [3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30]
Comprehensions com Laços Aninhados
# Gera pares de coordenadas — equivalente a laço for duplo
pairs = [(x, y) for x in range(3) for y in range(3)]
print(pairs)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# Aninhado com condição — encontra pares onde a soma é par
pairs = [(x, y) for x in range(3) for y in range(3) if (x + y) % 2 == 0]
print(pairs)
# [(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]
if-else em Comprehensions
# if-else em comprehensions — observe a posição diferente
numbers = [1, 2, 3, 4, 5, 6]
# Apenas if (filtragem) — colocado depois
evens = [n for n in numbers if n % 2 == 0]
# if-else (transformação) — colocado antes
result = ["par" if n % 2 == 0 else "ímpar" for n in numbers]
print(result) # ['ímpar', 'par', 'ímpar', 'par', 'ímpar', 'par']
Exemplo: Pipeline de Transformação de Dados (Dificuldade ⭐⭐⭐)
# Uma linha: filtrar → transformar → formatar
raw = [" maçã ", "BANANA", "", " CEREJA", None, " tâmara "]
# Filtra None e strings vazias → remove espaços → capitaliza
cleaned = [item.strip().capitalize() for item in raw if item and item.strip()]
print(cleaned) # ['Maçã', 'Banana', 'Cereja', 'Tâmara']
Saída:
['Maçã', 'Banana', 'Cereja', 'Tâmara']
3. Dict Comprehensions
Dicionários também podem usar comprehensions. A sintaxe é similar à de listas, mas usa {} e especifica pares chave-valor:
# Dict comprehension básica
squares = {x: x ** 2 for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Com condição
even_squares = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# Inverter chaves e valores
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {value: key for key, value in original.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
Prático: Mesclar Duas Listas em um Dict
# Mescla duas listas em um dicionário
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
result = {names[i]: scores[i] for i in range(len(names))}
print(result) # {'Alice': 85, 'Bob': 92, 'Charlie': 78}
# Usando zip() é mais elegante
result = {name: score for name, score in zip(names, scores)}
print(result) # {'Alice': 85, 'Bob': 92, 'Charlie': 78}
4. Set Comprehensions
Set comprehensions usam {} com apenas uma expressão (sem dois pontos) — a diferença de dict comprehensions é a presença ou ausência de dois pontos:
# Set comprehension — auto-deduplicação
numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16, 25}
# Com condição
even_set = {x for x in range(20) if x % 2 == 0}
print(even_set) # {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
[x for x in ...] é uma lista — ordenada, duplicatas permitidas. {x: y for x in ...} é um dict — tem dois pontos. {x for x in ...} é um set — sem dois pontos, não ordenado, deduplicado.
Exemplo: Análise de Vocabulário (Dificuldade ⭐⭐⭐)
# Analisa vocabulário em um artigo
article = """
Python é ótimo. Python é poderoso!
Eu amo Python. JavaScript também é ótimo.
Mas Python é meu favorito.
"""
# Extrai todas as palavras
words = article.lower().split()
# Deduplica com set comprehension
unique_words = {word.strip(".!,") for word in words}
print(f"Total de palavras: {len(words)}")
print(f"Palavras únicas: {len(unique_words)}")
print(f"Todas as palavras únicas: {sorted(unique_words)}")
Saída:
Total de palavras: 18
Palavras únicas: 10
Todas as palavras únicas: ['é', 'amo', 'favorito', 'javascript', 'mas', 'meu', 'ótimo', 'pod eroso', 'python', 'também']
Casos de Uso Comuns
- Pipeline de limpeza de dados: List comprehension para filtrar valores vazios, remover espaços e transformar formato em uma linha.
- Inversão de mapeamento de dicionário: Dict comprehension para trocar chaves e valores para busca reversa.
- Contagem de deduplicação: Set comprehension para estatísticas rápidas de elementos únicos.
- Agrupamento condicional: Comprehensions com if-else para dividir dados em dois grupos (como "aprovado/reprovado").
- Geração de coordenadas: Comprehensions aninhadas para coordenadas de tabuleiro de xadrez, grades de pixels, etc.
❓ Perguntas Frequentes
P: Qual a diferença entre list comprehensions e expressões geradoras? R: List comprehensions
[x for x in range(10)]geram todos os dados de uma vez na memória. Expressões geradoras(x for x in range(10))são preguiçosas — um valor de cada vez, economizando memória. Use geradores para grandes conjuntos de dados (dezenas de milhares+). ⚠️ P: E se uma comprehension tiver mais de dois níveis de aninhamento? R: Comprehensions com mais de dois níveis se tornam ilegíveis. Código como[x for xs in matrix for ys in xs for x in ys]é quase impossível de entender rapidamente. Se você precisar de três+ níveis, use laços for regulares ou funções auxiliares. P: Como decido qual container usar? R: Três perguntas: ① Precisa de chaves únicas? → dicionário. ② Precisa de dedup ou operações de conjunto? → set. ③ Os dados precisam mudar? → lista se sim, tupla se não. Na maioria dos cenários, listas e dicionários cobrem 90% dos casos de uso.
📖 Resumo
- Listas são ordenadas e mutáveis; tuplas são ordenadas e imutáveis; dicts são chave-valor com busca rápida; sets são para dedup e operações matemáticas
- List comprehension:
[expressão for variável in iterável if condição] - Dict comprehension:
{chave: valor for variável in iterável if condição} - Set comprehension:
{expressão for variável in iterável if condição} ifapós o laço é para filtragem;if-elseantes do laço é para transformação- Comprehensions aninhadas podem gerar dados 2D, mas mais de dois níveis pede laços regulares
📝 Atividades
-
Básico (Dificuldade ⭐): Use uma list comprehension para gerar todos os números entre 10 e 50 que são divisíveis por 7 ou contêm o dígito 7. Dica: Use
orpara combinar duas condições. -
Intermediário (Dificuldade ⭐⭐): Dadas duas listas
keys = ["name", "age", "city"]evalues = ["Alice", 25, "São Paulo"], use uma dict comprehension para mesclá-las em um dict. Dica: Usezip(keys, values)para pareá-las. -
Desafio (Dificuldade ⭐⭐⭐): Escreva um "analisador de dados." Dada uma string contendo múltiplas sentenças, conte e exiba: total de palavras, número de palavras únicas e as 3 palavras mais frequentes. Dica: Use
split()para tokenização, um dicionário para contagem, esorted(dict.items(), key=lambda x: x[1], reverse=True)[:3]para o top 3.



