Aula 10: Dicionários
Objetivos de Aprendizagem
Ao final desta aula, você será capaz de:
- Criar dicionários em Python e acessar valores por chave
- Adicionar, modificar e remover pares chave-valor
- Utilizar os métodos
.keys(),.values(),.items(),.get()e.update() - Iterar sobre dicionários de diferentes formas
- Escolher entre lista e dicionário conforme o problema
Conteúdo Teórico
1. O Problema que os Dicionários Resolvem
Imagine que você precisa armazenar dados de um aluno: nome, matrícula, curso e média. Com listas:
aluno = ["Maria", "2024001", "Ciência da Computação", 8.5]
# Para acessar a média, você precisa saber que ela está no índice 3
print(aluno[3]) # 8.5 — mas o índice não explica o que é esse valor
Com um dicionário, cada dado recebe um rótulo (chave) que explica seu significado:
aluno = {
"nome": "Maria",
"matricula": "2024001",
"curso": "Ciência da Computação",
"media": 8.5
}
print(aluno["media"]) # 8.5 — a chave explica o que estamos acessando
Um dicionário é uma estrutura de dados que armazena pares chave → valor. Cada chave é única dentro do dicionário e serve como identificador para acessar o valor correspondente. Em outras linguagens, estruturas equivalentes são chamadas de hash map, hash table ou associative array.
2. Criando Dicionários
Dicionários são delimitados por chaves {}. Cada par é escrito como chave: valor, separado por vírgulas:
# Dicionário com dados de um produto
produto = {
"nome": "Notebook",
"preco": 3500.00,
"estoque": 15,
"disponivel": True
}
# Dicionário vazio
configuracoes = {}
# Criando com a função dict()
cores = dict(vermelho="#FF0000", verde="#00FF00", azul="#0000FF")
Regras para chaves:
- Chaves devem ser de um tipo imutável:
str,int,float,tuple - O tipo mais comum e recomendado é
str(facilita a leitura) - Chaves são únicas — definir a mesma chave duas vezes sobrescreve o valor anterior
- Valores podem ser de qualquer tipo, incluindo listas e outros dicionários
3. Acessando e Modificando Valores
Acesso por chave
aluno = {"nome": "Maria", "media": 8.5, "curso": "BCC"}
print(aluno["nome"]) # Maria
print(aluno["media"]) # 8.5
Acessar uma chave inexistente gera um KeyError:
print(aluno["idade"]) # KeyError: 'idade'
Método .get() — acesso seguro
.get(chave) retorna None se a chave não existir, evitando o erro:
print(aluno.get("idade")) # None
print(aluno.get("idade", 0)) # 0 — valor padrão definido pelo programador
Verificar existência com in
print("nome" in aluno) # True
print("idade" in aluno) # False
Adicionar e modificar
aluno["matricula"] = "2024001" # adiciona nova chave
aluno["media"] = 9.0 # modifica valor existente
print(aluno)
# {"nome": "Maria", "media": 9.0, "curso": "BCC", "matricula": "2024001"}
Remover pares
del aluno["curso"] # remove o par — KeyError se não existir
valor = aluno.pop("media") # remove e retorna o valor
print(valor) # 9.0
4. Iterando sobre Dicionários
Iterando sobre chaves (padrão)
produto = {"nome": "Notebook", "preco": 3500.0, "estoque": 15}
for chave in produto:
print(chave)
# nome
# preco
# estoque
.keys(), .values() e .items()
| Método | Retorna |
|---|---|
.keys() | Sequência de todas as chaves |
.values() | Sequência de todos os valores |
.items() | Sequência de tuplas (chave, valor) |
for chave in produto.keys():
print(chave)
for valor in produto.values():
print(valor)
for chave, valor in produto.items():
print(f"{chave}: {valor}")
# nome: Notebook
# preco: 3500.0
# estoque: 15
.items() é o método mais usado em iterações porque fornece chave e valor juntos, eliminando a necessidade de um segundo acesso produto[chave].
5. Outros Métodos Úteis
config = {"tema": "escuro", "idioma": "pt-BR", "fonte": 14}
# .update() — mescla outro dicionário (ou pares chave=valor)
config.update({"fonte": 16, "zoom": 100})
print(config)
# {"tema": "escuro", "idioma": "pt-BR", "fonte": 16, "zoom": 100}
# len() — número de pares
print(len(config)) # 4
# .clear() — remove todos os pares
backup = dict(config) # cópia antes de limpar
config.clear()
print(config) # {}
6. Exemplo Prático: Contagem de Frequência
Um uso clássico de dicionários é contar ocorrências:
texto = "abracadabra"
frequencia = {}
for letra in texto:
if letra in frequencia:
frequencia[letra] += 1
else:
frequencia[letra] = 1
print(frequencia)
# {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
O mesmo resultado com .get():
frequencia = {}
for letra in texto:
frequencia[letra] = frequencia.get(letra, 0) + 1
7. Lista vs. Dicionário — Quando Usar Cada Um?
| Critério | Lista | Dicionário |
|---|---|---|
| Acesso | Por índice numérico | Por chave descritiva |
| Semântica | Sequência de itens similares | Registro com atributos nomeados |
| Ordem | Preservada (Python 3.7+) | Preservada (Python 3.7+) |
| Busca por chave | O(n) — percorre tudo | O(1) — acesso direto |
| Exemplo típico | [nota1, nota2, nota3] | {"nome": "João", "nota": 8.0} |
Use lista quando os elementos são da mesma natureza e a posição importa (notas, dias, produtos).
Use dicionário quando cada dado tem um nome (atributo) e você acessa pelo rótulo (aluno, configuração, produto).
Exercícios / Checkpoints
Checkpoint 1: Criação e acesso
Crie um dicionário representando um livro com as chaves: titulo, autor, ano e paginas. Imprima cada valor acessando pela chave. Em seguida, tente acessar uma chave inexistente usando .get() com um valor padrão de sua escolha.
Checkpoint 2: Modificação
Dado o dicionário abaixo, faça as operações indicadas e imprima o resultado após cada uma:
estoque = {"arroz": 50, "feijão": 30, "macarrão": 20}
- Adicione
"sal"com quantidade100 - Atualize a quantidade de
"feijão"para45 - Remova
"macarrão"e capture o valor removido em uma variável
Checkpoint 3: Iteração com .items()
Escreva um programa que imprima o inventário abaixo no formato "Produto: X | Quantidade: Y | Total: R$ Z", onde Total = quantidade × preco:
produtos = {
"caneta": {"quantidade": 100, "preco": 2.50},
"caderno": {"quantidade": 30, "preco": 15.90},
"borracha": {"quantidade": 75, "preco": 1.20},
}
Checkpoint 4: Contagem de frequência
Escreva um programa que leia uma frase e conte quantas vezes cada palavra aparece. Imprima as palavras e suas contagens em ordem alfabética.
(Dica: frase.split() separa a string em lista de palavras; sorted(dicionario) ordena as chaves.)
Checkpoint 5: Lista vs. Dicionário
Para cada situação abaixo, justifique se usaria uma lista ou um dicionário:
- Armazenar as temperaturas de uma cidade ao longo de 30 dias
- Armazenar os dados de um funcionário (nome, CPF, cargo, salário)
- Armazenar os 10 filmes mais assistidos na plataforma (em ordem)
- Armazenar o placar de cada jogador em um jogo
Situações Problema
As duas situações abaixo são para implementação em aula. Elas exigem a combinação de vários conceitos da aula — não há uma única solução certa. Incentive os alunos a experimentar, errar e discutir abordagens diferentes.
Situação Problema 1: Apuração de Votos em Eleição de Representante
Contexto: Uma turma está elegendo seu representante discente. Cada aluno escreveu o nome do candidato de sua preferência em um papel. Os votos foram digitados na lista abaixo. Votos nulos são identificados pela string "nulo".
Código inicial:
votos = [
"Alice", "Bruno", "Alice", "nulo", "Carlos", "Alice",
"Bruno", "nulo", "Carlos","Bruno", "Alice", "Carlos",
"Bruno", "Alice", "nulo", "Bruno", "Carlos", "Alice",
]
Tarefas:
- Contabilize os votos de cada candidato, ignorando os nulos na contagem por candidato (registre o total de nulos separado).
- Determine o(s) vencedor(es) — quem obteve mais votos válidos.
- Exiba o resultado completo: total de votos válidos, percentual de cada candidato e o nome do vencedor. Mostre os candidatos em ordem decrescente de votos.
- Detecte empate: se dois ou mais candidatos dividirem o primeiro lugar, liste todos e informe que haverá segundo turno.
key=lambdaNo trecho sorted(contagem.items(), key=lambda par: par[1], reverse=True),
key= define o critério de ordenação e lambda par: par[1] significa:
"para cada par (chave, valor), use o valor (par[1]) para ordenar".
Para ordenar um dicionário por valor decrescente:
sorted(contagem.items(), key=lambda par: par[1], reverse=True)
Saída esperada:
Total de votos: 18
Votos válidos : 15
Votos nulos : 3
Resultado (ordem decrescente):
Alice: 6 voto(s) — 40.0%
Bruno: 5 voto(s) — 33.3%
Carlos: 4 voto(s) — 26.7%
Vencedor: Alice com 6 voto(s).
Ver solução
# Tarefa 1: contabilizar votos (excluindo nulos)
contagem = {}
total_nulos = 0
for voto in votos:
if voto == "nulo":
total_nulos += 1
else:
contagem[voto] = contagem.get(voto, 0) + 1
# Tarefa 2: determinar vencedor(es)
total_validos = sum(contagem.values())
max_votos = 0
for qtd in contagem.values():
if qtd > max_votos:
max_votos = qtd
vencedores = []
for candidato, qtd in contagem.items():
if qtd == max_votos:
vencedores.append(candidato)
# Tarefa 3: resultado em ordem decrescente de votos
print(f"Total de votos: {len(votos)}")
print(f"Votos válidos : {total_validos}")
print(f"Votos nulos : {total_nulos}")
print("\nResultado (ordem decrescente):")
for candidato, qtd in sorted(contagem.items(), key=lambda par: par[1], reverse=True):
percentual = qtd / total_validos * 100
print(f" {candidato}: {qtd} voto(s) — {percentual:.1f}%")
# Tarefa 4: detectar empate
print()
if len(vencedores) > 1:
print(f"Empate! Haverá segundo turno entre: {', '.join(vencedores)}.")
else:
print(f"Vencedor: {vencedores[0]} com {max_votos} voto(s).")
Situação Problema 2: Controle de Estoque com Relatório de Vendas
Contexto: Uma pequena loja registrou todas as transações do dia. Cada transação é um dicionário com produto, quantidade vendida e preço unitário. O estoque inicial de cada produto é fornecido separadamente.
Código inicial:
transacoes = [
{"produto": "caneta", "quantidade": 12, "preco": 2.50},
{"produto": "caderno", "quantidade": 5, "preco": 15.90},
{"produto": "caneta", "quantidade": 8, "preco": 2.50},
{"produto": "borracha", "quantidade": 20, "preco": 1.20},
{"produto": "caderno", "quantidade": 3, "preco": 15.90},
{"produto": "caneta", "quantidade": 5, "preco": 2.50},
{"produto": "mochila", "quantidade": 2, "preco": 89.90},
{"produto": "borracha", "quantidade": 15, "preco": 1.20},
]
estoque_inicial = {
"caneta": 50, "caderno": 15, "borracha": 40, "mochila": 5
}
Tarefas:
- Calcule o total de unidades vendidas e o faturamento por produto. Armazene em um dicionário no formato
{"caneta": {"unidades": 25, "faturamento": 62.50}, ...}. Atenção: o mesmo produto aparece em múltiplas transações. - Identifique o produto mais vendido (por unidades) e o de maior faturamento (podem ser diferentes).
- Partindo do estoque inicial, calcule o estoque restante e liste os produtos abaixo do estoque mínimo de 5 unidades.
- Exiba um relatório formatado com todas as informações acima.
Use .get() ou verifique a existência da chave antes de acumular — o mesmo produto aparece em múltiplas linhas de transação.
Saída esperada:
====================================================
RELATÓRIO DE VENDAS
====================================================
Produto | Unidades | Faturamento
----------------------------------------------------
caneta | 25 | R$ 62.50
caderno | 8 | R$ 127.20
borracha | 35 | R$ 42.00
mochila | 2 | R$ 179.80
----------------------------------------------------
Mais vendido (unidades) : borracha (35 un.)
Maior faturamento : mochila (R$ 179.80)
Estoque restante:
caneta : 25 un.
caderno : 7 un.
borracha : 5 un.
mochila : 3 un. *** ABAIXO DO MÍNIMO ***
ALERTA: repor estoque de: mochila.
====================================================
Ver solução
# Tarefa 1: unidades vendidas e faturamento por produto
relatorio = {}
for t in transacoes:
produto = t["produto"]
if produto not in relatorio:
relatorio[produto] = {"unidades": 0, "faturamento": 0.0}
relatorio[produto]["unidades"] += t["quantidade"]
relatorio[produto]["faturamento"] += t["quantidade"] * t["preco"]
# Tarefa 2: produto mais vendido e de maior faturamento
mais_vendido = None
maior_unidades = 0
maior_fat_nome = None
maior_fat = 0.0
for produto, dados in relatorio.items():
if dados["unidades"] > maior_unidades:
maior_unidades = dados["unidades"]
mais_vendido = produto
if dados["faturamento"] > maior_fat:
maior_fat = dados["faturamento"]
maior_fat_nome = produto
# Tarefa 3: estoque restante e alertas de mínimo
ESTOQUE_MINIMO = 5
estoque_restante = {}
abaixo_minimo = []
for produto, inicial in estoque_inicial.items():
vendidas = relatorio.get(produto, {}).get("unidades", 0)
restante = inicial - vendidas
estoque_restante[produto] = restante
if restante < ESTOQUE_MINIMO:
abaixo_minimo.append(produto)
# Tarefa 4: relatório formatado
print("=" * 52)
print("RELATÓRIO DE VENDAS")
print("=" * 52)
print(f"{'Produto':<12} | {'Unidades':>8} | {'Faturamento':>12}")
print("-" * 52)
for produto, dados in relatorio.items():
print(f"{produto:<12} | {dados['unidades']:>8} | R$ {dados['faturamento']:>9.2f}")
print("-" * 52)
print(f"\nMais vendido (unidades) : {mais_vendido} ({maior_unidades} un.)")
print(f"Maior faturamento : {maior_fat_nome} (R$ {maior_fat:.2f})")
print("\nEstoque restante:")
for produto, qtd in estoque_restante.items():
alerta = " *** ABAIXO DO MÍNIMO ***" if produto in abaixo_minimo else ""
print(f" {produto:<12}: {qtd:>3} un.{alerta}")
if abaixo_minimo:
print(f"\nALERTA: repor estoque de: {', '.join(abaixo_minimo)}.")
print("=" * 52)
Resumo da Aula
Nesta aula, você aprendeu:
- Dicionários armazenam pares chave-valor; as chaves são únicas e descritivas
- Valores são acessados por chave (
dic["chave"]) ou com.get()para acesso seguro .keys(),.values()e.items()permitem diferentes formas de iteração.update()mescla dicionários;dele.pop()removem pares- Use lista para sequências homogêneas; use dicionário para registros com atributos nomeados
Próxima aula: Tuplas e Conjuntos — outras estruturas de dados do Python com propriedades distintas
Referências
Leitura Essencial
- Python Software Foundation. Mapping Types — dict. Documentação oficial do Python.
Disponível em: docs.python.org/3/library/stdtypes.html#mapping-types-dict
- Referência completa de todos os métodos e comportamentos de dicionários.
- Forbellone, A. L. V.; Eberspächer, H. F. Lógica de Programação: A Construção de Algoritmos e Estruturas de Dados. 3ª ed. São Paulo: Pearson, 2005.
- Base conceitual para estruturas de dados associativas.
Aprofundamento (Opcional)
- Python Software Foundation. Dictionary view objects. Disponível em: docs.python.org/3/library/stdtypes.html#dictionary-view-objects
- Detalha o comportamento de
.keys(),.values()e.items()como views dinâmicas.
- Detalha o comportamento de
- Python Software Foundation. collections.defaultdict. Disponível em: docs.python.org/3/library/collections.html#collections.defaultdict
- Variante de dicionário que elimina verificações de chave inexistente — útil em contagem e agrupamento.