Dicionários: estrutura chave-valor fundamental
1. Introdução aos Dicionários em Python
Os dicionários são uma das estruturas de dados mais versáteis e poderosas do Python. Eles implementam o conceito de mapeamento chave-valor, onde cada elemento armazenado é associado a uma chave única que permite acesso direto e eficiente ao seu valor correspondente. Diferente de listas ou tuplas, que são indexadas por posições numéricas, os dicionários utilizam chaves personalizadas como identificadores.
A sintaxe básica para criar um dicionário utiliza chaves {} ou a função construtora dict():
# Criando dicionários
vazio1 = {}
vazio2 = dict()
aluno = {"nome": "Carlos", "idade": 25, "curso": "Engenharia"}
print(aluno) # {'nome': 'Carlos', 'idade': 25, 'curso': 'Engenharia'}
Os dicionários possuem três características fundamentais:
- Mutabilidade: é possível adicionar, remover ou modificar pares após a criação
- Chaves únicas: cada chave aparece apenas uma vez no dicionário
- Chaves imutáveis: as chaves devem ser de tipos imutáveis (strings, números, tuplas), enquanto os valores podem ser de qualquer tipo
2. Criando e Acessando Dicionários
A forma mais comum de criar dicionários é através de literais, especificando pares chave:valor separados por vírgulas:
# Inicialização com literais
contato = {
"nome": "Ana Silva",
"email": "ana@email.com",
"telefone": "(11) 99999-8888",
"ativo": True
}
# Acesso a valores
print(contato["nome"]) # Ana Silva
# Usando o método get() - mais seguro
print(contato.get("email")) # ana@email.com
print(contato.get("endereco", "Não informado")) # Não informado
A diferença crucial entre o acesso direto e o método get() está no tratamento de chaves inexistentes:
# Acesso direto gera KeyError
# print(contato["endereco"]) # KeyError: 'endereco'
# get() retorna None ou valor padrão
resultado = contato.get("endereco")
print(resultado) # None
3. Manipulação de Dicionários: Adição, Alteração e Remoção
A manipulação de dicionários é intuitiva e direta:
estoque = {"caneta": 50, "caderno": 30}
# Adicionar novo par
estoque["lapis"] = 100
print(estoque) # {'caneta': 50, 'caderno': 30, 'lapis': 100}
# Atualizar valor existente
estoque["caneta"] = 45
print(estoque) # {'caneta': 45, 'caderno': 30, 'lapis': 100}
# Remoção com del
del estoque["caderno"]
print(estoque) # {'caneta': 45, 'lapis': 100}
# Remoção com pop() - retorna o valor removido
item_removido = estoque.pop("lapis")
print(f"Removido: {item_removido}") # Removido: 100
print(estoque) # {'caneta': 45}
# popitem() remove e retorna o último par (Python 3.7+)
ultimo_par = estoque.popitem()
print(ultimo_par) # ('caneta', 45)
# Limpeza total
estoque.clear()
print(estoque) # {}
# Verificação de existência
config = {"tema": "escuro", "idioma": "pt-BR"}
print("tema" in config) # True
print("zoom" in config) # False
4. Métodos Essenciais para Navegação e Iteração
Python oferece métodos específicos para iterar sobre diferentes componentes do dicionário:
vendas = {
"João": 1500,
"Maria": 2300,
"Pedro": 1800,
"Ana": 2100
}
# Iteração sobre chaves (padrão)
print("Vendedores:")
for vendedor in vendas:
print(f"- {vendedor}")
# Equivalente explícito com keys()
for vendedor in vendas.keys():
print(f"- {vendedor}")
# Iteração sobre valores
print("\nValores de venda:")
for valor in vendas.values():
print(f"R$ {valor:.2f}")
# Iteração sobre pares com desempacotamento
print("\nRelatório completo:")
for nome, total in vendas.items():
print(f"{nome}: R$ {total:.2f}")
5. Operações Avançadas e Combinando Dicionários
Combinar dicionários é uma operação comum que pode ser feita de várias formas:
# União com update()
dados1 = {"a": 1, "b": 2}
dados2 = {"c": 3, "d": 4}
dados1.update(dados2)
print(dados1) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Operador | (Python 3.9+)
base = {"nome": "Maria", "idade": 28}
extra = {"cidade": "São Paulo", "profissao": "Engenheira"}
completo = base | extra
print(completo) # {'nome': 'Maria', 'idade': 28, 'cidade': 'São Paulo', 'profissao': 'Engenheira'}
# Cópia superficial
original = {"chave": [1, 2, 3]}
copia1 = original.copy()
copia2 = dict(original)
# Cópia profunda (necessária para estruturas aninhadas)
from copy import deepcopy
copia_profunda = deepcopy(original)
# Compreensão de dicionários
quadrados = {x: x**2 for x in range(5)}
print(quadrados) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Filtrando com dict comprehension
pares = {k: v for k, v in quadrados.items() if v % 2 == 0}
print(pares) # {0: 0, 2: 4, 4: 16}
6. Chaves e Valores: Restrições e Boas Práticas
As chaves em dicionários devem ser imutáveis, enquanto os valores podem ser qualquer objeto Python:
# Chaves válidas
valido = {
"string": 1, # strings
42: "número", # inteiros
3.14: "pi", # floats
(1, 2): "tupla", # tuplas (com elementos imutáveis)
True: "booleano" # booleanos (são subclasse de int)
}
# Chaves inválidas (geram TypeError)
# invalido = {[1, 2]: "lista"} # TypeError: unhashable type: 'list'
# Boas práticas com defaultdict
from collections import defaultdict
# Evita verificar existência antes de acessar
contagem = defaultdict(int)
palavras = ["banana", "maçã", "banana", "pera", "banana"]
for palavra in palavras:
contagem[palavra] += 1
print(dict(contagem)) # {'banana': 3, 'maçã': 1, 'pera': 1}
7. Dicionários no Mundo Real: Casos de Uso Comuns
Contagem de Frequências
texto = "python é uma linguagem python muito poderosa python"
frequencia = {}
for palavra in texto.split():
frequencia[palavra] = frequencia.get(palavra, 0) + 1
print(frequencia)
# {'python': 3, 'é': 1, 'uma': 1, 'linguagem': 1, 'muito': 1, 'poderosa': 1}
Agrupamento de Dados
alunos = [
("Ana", "Matemática"), ("Pedro", "Física"), ("Maria", "Matemática"),
("João", "Química"), ("Carla", "Física"), ("Lucas", "Matemática")
]
turmas = {}
for nome, disciplina in alunos:
if disciplina not in turmas:
turmas[disciplina] = []
turmas[disciplina].append(nome)
print(turmas)
# {'Matemática': ['Ana', 'Maria', 'Lucas'], 'Física': ['Pedro', 'Carla'], 'Química': ['João']}
Cache e Memoização
def fibonacci_memo(n, cache={}):
if n in cache:
return cache[n]
if n <= 1:
return n
cache[n] = fibonacci_memo(n-1, cache) + fibonacci_memo(n-2, cache)
return cache[n]
print(fibonacci_memo(10)) # 55
print(fibonacci_memo(50)) # 12586269025 (rápido graças ao cache)
8. Comparação com Estruturas Vizinhas e Considerações Finais
A escolha entre dicionários e outras estruturas depende do caso de uso:
# Quando usar dicionários vs listas
# Dicionário: acesso por chave (O(1))
contato_dict = {"email": "ana@email.com"}
print(contato_dict["email"]) # Rápido: O(1)
# Lista: acesso por índice ou busca linear
contato_list = ["ana@email.com", "(11) 99999-8888"]
# Para encontrar o email, precisamos saber o índice ou buscar
# Performance: busca em dicionário vs lista
import time
grande_dict = {i: i**2 for i in range(100000)}
grande_lista = list(range(100000))
# Busca em dicionário é O(1)
inicio = time.time()
print(99999 in grande_dict) # True
print(f"Dicionário: {time.time() - inicio:.6f}s")
# Busca em lista é O(n)
inicio = time.time()
print(99999 in grande_lista) # True
print(f"Lista: {time.time() - inicio:.6f}s")
Armadilhas comuns a evitar:
- Cópias acidentais: modificar um dicionário copiado superficialmente pode afetar o original em estruturas aninhadas
- Chaves duplicadas: ao criar um dicionário, chaves repetidas sobrescrevem valores anteriores
- Mutabilidade interna: valores mutáveis (listas, dicionários) dentro de um dicionário podem causar efeitos colaterais
Os dicionários são fundamentais para programação Python eficiente. Dominá-los significa ter uma ferramenta poderosa para organizar, acessar e manipular dados com clareza e performance.
Referências
- Documentação Oficial de Dicionários em Python — Guia completo da documentação oficial sobre dicionários, incluindo métodos e exemplos
- Python Dicionários: Um Guia Completo (Real Python) — Tutorial abrangente com exemplos práticos e casos de uso avançados
- Coleções em Python: defaultdict, Counter e OrderedDict — Documentação do módulo collections com tipos especiais de dicionários
- Dicionários em Python: Guia para Iniciantes (GeeksforGeeks) — Tutorial introdutório cobrindo operações básicas e intermediárias
- Performance de Dicionários em Python (Pythontips) — Artigo técnico sobre implementação interna e performance de dicionários como tabelas hash
- Compreensão de Dicionários em Python (Programiz) — Tutorial focado em dict comprehension com exemplos detalhados
- Python Dicionários Aninhados: Estruturas Complexas de Dados — Guia prático para trabalhar com dicionários dentro de dicionários