Python Adicionando e Removendo Chaves

Na aula Dicionários, a tabela de preços da padaria já nasceu pronta. Na vida real ela muda o tempo todo: chega um produto novo, o pão sobe de preço, o bolo sai do cardápio. Esta aula mostra como mudar um dicionário depois de criado: acrescentar pares, trocar valores e remover chaves, e um truque que você vai usar muito, o de contar coisas com um dicionário.

Você vai aprender
  • A acrescentar um par e a trocar um valor com a mesma escrita: d[chave] = valor.
  • A juntar dois dicionários com update() e com |.
  • A remover com del, pop(), popitem() e clear(), e qual escolher.
  • A contar quantas vezes cada coisa aparece com contagem.get(item, 0) + 1.
  • Os KeyError reais ao remover ou somar numa chave que não existe.

A ideia: o quadro de preços com giz

A padaria do bairro tem um quadro-negro com os preços escritos a giz. Para um produto novo, a Ana escreve uma linha nova. Para mudar um preço, ela apaga só o número e escreve o novo, na mesma linha. Para tirar um produto, apaga a linha inteira. O quadro é o dicionário; o nome do produto, que nunca se repete, é a chave.


1. Acrescentar e trocar: d[chave] = valor

Você já sabe ler com precos["leite"]. Para escrever, é a mesma coisa do lado esquerdo do =:

precos = {"pão": 0.50, "leite": 4.75}
precos["bolo"] = 12.00
print(precos)
precos["pão"] = 0.60
print(precos)
print(len(precos))
$ python3 a_add.py
{'pão': 0.5, 'leite': 4.75, 'bolo': 12.0}
{'pão': 0.6, 'leite': 4.75, 'bolo': 12.0}
3
precos["bolo"] = 12.00
A chave "bolo" não existia: o Python cria o par e o põe no fim (lembre: o dicionário guarda a ordem de chegada).
precos["pão"] = 0.60
A chave "pão" já existia: o valor antigo é trocado pelo novo. O pão continua no mesmo lugar, o primeiro.
len(precos)
Três pares: trocar um valor não cria chave nova.

A mesma linha faz duas coisas: se a chave existe, troca; se não existe, cria. Isso é cômodo, mas tem um lado perigoso: um erro de digitação (precos["paõ"] = 0.60) não dá erro nenhum; cria uma chave nova e deixa o preço do pão como estava.

Os operadores de atribuição (aula Operadores de Atribuição) também funcionam num valor que já existe. Saíram 10 pães e chegaram 6 leites:

estoque = {"pão": 40, "leite": 12}
estoque["pão"] -= 10
estoque["leite"] += 6
print(estoque)
$ python3 a_mais_igual.py
{'pão': 30, 'leite': 18}

Missão: o pão subiu para 0.60 e a padaria passou a vender bolo a 12.00. Antes do print, troque o preço do pão e acrescente o bolo.

precos = {"pão": 0.50, "leite": 4.75}
# mude o dicionário aqui
print(precos)
precos = {"pão": 0.50, "leite": 4.75}
precos["pão"] = 0.60
precos["bolo"] = 12.00
print(precos)

2. Vários de uma vez: update() e |

Chegou a tabela nova do fornecedor, com o leite mais caro e um produto novo. Em vez de uma linha por produto, junte os dois dicionários com update ("atualizar"):

precos = {"pão": 0.60, "leite": 4.75}
novidades = {"leite": 5.10, "café": 18.90}
precos.update(novidades)
print(precos)
precos.update(suco=7.00)
print(precos)
$ python3 a_update.py
{'pão': 0.6, 'leite': 5.1, 'café': 18.9}
{'pão': 0.6, 'leite': 5.1, 'café': 18.9, 'suco': 7.0}

Cada par de novidades é aplicado como um precos[chave] = valor: o leite, que existia, foi trocado; o café, que não existia, foi acrescentado. Na segunda chamada, suco=7.00 é um atalho para chaves de texto simples.

O |: juntar sem mexer no original

O update muda o próprio dicionário. Para um dicionário novo, deixando o original como está, use a barra |, a mesma da união de conjuntos:

loja = {"pão": 0.60, "leite": 4.75}
promocao = {"leite": 3.99}
hoje = loja | promocao
print(hoje)
print(loja)
loja |= {"café": 18.90}
print(loja)
$ python3 a_uniao.py
{'pão': 0.6, 'leite': 3.99}
{'pão': 0.6, 'leite': 4.75}
{'pão': 0.6, 'leite': 4.75, 'café': 18.9}
loja | promocao
Um dicionário novo com os pares dos dois. Quando a chave está nos dois (o leite), vale o valor do lado direito.
print(loja)
O original não mudou: o leite continua a 4.75.
loja |= {…}
Com o = junto, muda o próprio loja, como o update.
Versões do Python

O | e o |= entre dicionários existem desde o Python 3.9. O Ubuntu 26.04 (3.14) e o Debian 13 (3.13) já têm; se você encontrar um Python muito antigo, use update.


3. Removendo

Há quatro jeitos de tirar coisas de um dicionário. Todos de uma vez, no estoque da padaria:

estoque = {"pão": 40, "leite": 12, "bolo": 3, "café": 8}
del estoque["bolo"]
print(estoque)
leite = estoque.pop("leite")
print("Tirei o leite, que tinha", leite)
print(estoque)
print(estoque.pop("suco", 0))
ultimo = estoque.popitem()
print(ultimo)
print(estoque)
estoque.clear()
print(estoque)
$ python3 a_del.py
{'pão': 40, 'leite': 12, 'café': 8}
Tirei o leite, que tinha 12
{'pão': 40, 'café': 8}
0
('café', 8)
{'pão': 40}
{}
del estoque["bolo"]
del ("apagar") tira a chave e o valor. Não devolve nada.
estoque.pop("leite")
"Tirar": remove o par e devolve o valor, que você pode guardar numa variável (aqui, o 12).
estoque.pop("suco", 0)
Com um segundo valor, o pop não dá erro se a chave não existir: devolve esse valor (0) e não remove nada.
estoque.popitem()
Remove o último par que entrou e o devolve como tupla (chave, valor): ('café', 8).
estoque.clear()
"Limpar": tira tudo. Sobra {}, o dicionário vazio.
Para…UseSe a chave não existe
Tirar uma chave e não precisar do valordel d[chave]KeyError
Tirar uma chave e usar o valord.pop(chave)KeyError
Tirar se existir, sem risco de errod.pop(chave, None)Devolve None
Tirar o último par que entroud.popitem()KeyError se estiver vazio
Esvaziard.clear()—

"Renomear" uma chave

Não existe um jeito de mudar o nome de uma chave. O truque é tirar o valor com pop e guardá-lo numa chave nova, numa linha só:

precos = {"pao": 0.60, "leite": 4.75}
precos["pão"] = precos.pop("pao")
print(precos)
$ python3 a_renomear.py
{'leite': 4.75, 'pão': 0.6}

O "pão" foi para o fim, porque é uma chave nova, que acabou de entrar.

Missão: o bolo saiu do cardápio. Tire a chave "bolo" do estoque com pop, guardando quantos bolos havia, para o programa mostrar Bolos retirados: 3 e o estoque sem o bolo.

estoque = {"pão": 40, "leite": 12, "bolo": 3}
bolos = 0
print("Bolos retirados:", bolos)
print(estoque)
estoque = {"pão": 40, "leite": 12, "bolo": 3}
bolos = estoque.pop("bolo")
print("Bolos retirados:", bolos)
print(estoque)

4. O truque de contar

A Ana anotou cada venda do dia numa lista e quer saber quantas vezes cada produto saiu. O dicionário é perfeito para isso: a chave é o produto, o valor é quantas vezes ele apareceu.

vendas = ["pão", "leite", "pão", "café", "pão", "leite"]
contagem = {}
for item in vendas:
    contagem[item] = contagem.get(item, 0) + 1
print(contagem)
$ python3 a_contar.py
{'pão': 3, 'leite': 2, 'café': 1}
  1. Começa com um dicionário vazio.
  2. Primeiro item, "pão": contagem.get("pão", 0) não acha a chave e devolve 0; mais 1 dá 1; contagem["pão"] = 1 cria a chave.
  3. Segundo item, "leite": o mesmo, contagem["leite"] = 1.
  4. Terceiro item, "pão" de novo: agora get acha o 1; mais 1 dá 2; o valor é trocado por 2.
  5. …e assim até o fim da lista.

O segredo é o get(item, 0): na primeira vez que um produto aparece, ele faz de conta que o valor era zero. A mesma conta, escrita com if, fica mais comprida mas talvez mais fácil de ler no começo:

vendas = ["pão", "leite", "pão", "café", "pão", "leite"]
contagem = {}
for item in vendas:
    if item in contagem:
        contagem[item] += 1
    else:
        contagem[item] = 1
print(contagem)
$ python3 a_contar_if.py
{'pão': 3, 'leite': 2, 'café': 1}

Mesmo resultado. Contar é tão comum que o Python tem até uma ferramenta pronta, o Counter, da aula O Módulo collections. Mas vale entender primeiro o jeito "na mão".

setdefault: ler ou criar

Existe também d.setdefault(chave, valor): se a chave existe, devolve o valor dela e não muda nada; se não existe, cria com o valor dado e o devolve.

precos = {"pão": 0.60}
print(precos.setdefault("pão", 1.00))
print(precos.setdefault("bolo", 12.00))
print(precos)
$ python3 a_setdefault.py
0.6
12.0
{'pão': 0.6, 'bolo': 12.0}

Formas diferentes de fazer a mesma coisa

ObjetivoFormasQual usar
Acrescentar ou trocar um pard["k"] = v · d.update({"k": v})d["k"] = v para um par; update para vários
Juntar dois dicionáriosa.update(b) · a |= b · c = a | ba | b quando quer manter o original; os outros mudam a
Remover uma chavedel d["k"] · d.pop("k")pop quando vai usar o valor; del quando não
Remover sem risco de errod.pop("k", None) · if "k" in d: del d["k"]O pop com padrão, mais curto
Contard[x] = d.get(x, 0) + 1 · if/elseO get, que é o costume

Quando dá errado

Somar numa chave que ainda não existe

A forma mais curta de contar parece ser contagem[item] += 1. Mas:

vendas = ["pão", "leite", "pão"]
contagem = {}
for item in vendas:
    contagem[item] += 1
$ python3 a_contar_erro.py
Traceback (most recent call last):
  File "/home/ana/a_contar_erro.py", line 4, in <module>
    contagem[item] += 1
    ~~~~~~~~^^^^^^
KeyError: 'pão'
line 4
O erro está na linha 4, dentro do for, logo na primeira volta.
contagem[item] += 1
É o mesmo que contagem[item] = contagem[item] + 1. Para somar 1, o Python precisa primeiro ler contagem["pão"]…
KeyError: 'pão'
…e essa chave ainda não existe. Não há valor antigo para somar.

Como consertar: contagem[item] = contagem.get(item, 0) + 1, ou o if item in contagem da seção 4.

Apagar uma chave que não existe
estoque = {"pão": 40, "leite": 12}
del estoque["bolo"]
$ python3 a_del_erro.py
Traceback (most recent call last):
  File "/home/ana/a_del_erro.py", line 2, in <module>
    del estoque["bolo"]
        ~~~~~~~^^^^^^^^
KeyError: 'bolo'

O mesmo KeyError da leitura: não há bolo para apagar. Com pop sem padrão acontece igual:

estoque = {"pão": 40, "leite": 12}
estoque.pop("bolo")
$ python3 a_pop_erro.py
Traceback (most recent call last):
  File "/home/ana/a_pop_erro.py", line 2, in <module>
    estoque.pop("bolo")
    ~~~~~~~~~~~^^^^^^^^
KeyError: 'bolo'

Como consertar: estoque.pop("bolo", None) remove se existir e fica quieto se não existir.

popitem() num dicionário vazio
estoque = {}
estoque.popitem()
$ python3 a_popitem_erro.py
Traceback (most recent call last):
  File "/home/ana/a_popitem_erro.py", line 2, in <module>
    estoque.popitem()
    ~~~~~~~~~~~~~~~^^
KeyError: 'popitem(): dictionary is empty'

Aqui o KeyError vem com uma frase em vez do nome de uma chave: "popitem(): o dicionário está vazio". Como consertar: confira antes: if estoque: estoque.popitem() (dicionário vazio conta como falso).

Erro de digitação na chave: sem erro, resultado errado

precos["paõ"] = 0.60 (com o til no lugar errado) não dá erro nenhum. Como a chave "paõ" não existe, o Python a cria, e o dicionário fica com o pão antigo e mais um "paõ" novo. Como perceber: mostre o dicionário depois de mudar, ou confira o len: se ele cresceu quando você só queria trocar um preço, alguma chave saiu escrita diferente.


Referência rápida

EscritaO que faz
d[k] = vCria o par (chave nova) ou troca o valor (chave existente)
d[k] += 1Soma no valor existente (KeyError se a chave não existe)
d.update(outro)Aplica todos os pares de outro em d
a | b / a |= bDicionário novo com os dois / muda a (vale o da direita)
del d[k]Remove a chave
d.pop(k) / d.pop(k, padrao)Remove e devolve o valor / sem erro se não existir
d.popitem()Remove e devolve o último par, como tupla
d.clear()Esvazia
d.setdefault(k, v)Devolve o valor de k; se não existir, cria com v
d[x] = d.get(x, 0) + 1Conta quantas vezes x aparece
MensagemCausa provável
KeyError: 'pão' numa linha com +=Somou numa chave que ainda não existe: use get(k, 0) + 1
KeyError: 'bolo' num del ou popA chave não existe: use pop(k, None)
KeyError: 'popitem(): dictionary is empty'popitem() com o dicionário vazio
O len cresceu quando era só trocarChave escrita diferente: virou chave nova

Exercícios

1. Produto novo

Complete para acrescentar o suco a 7.00:

precos[] = 7.00

2. Apagar

Complete a palavra que apaga a chave "bolo":

estoque["bolo"]

3. Contando

Complete o valor padrão do get na linha que conta:

contagem[item] = contagem.get(item, ) + 1

4. Com d = {"a": 1}, o que acontece em d["a"] = 5?

5. Qual remove a chave "x" e devolve o valor dela?

6. Em {"leite": 4.75} | {"leite": 3.99}, qual preço do leite fica?

Missão final: a votação do sorvete

Missão: a turma votou no sabor do sorvete da festa. O programa quer contar os votos de cada sabor, mas para com KeyError: 'morango'. Conserte a linha de dentro do for.

votos = ["morango", "chocolate", "morango", "coco", "morango", "chocolate"]
contagem = {}
for sabor in votos:
    contagem[sabor] += 1
print(contagem)
votos = ["morango", "chocolate", "morango", "coco", "morango", "chocolate"]
contagem = {}
for sabor in votos:
    contagem[sabor] = contagem.get(sabor, 0) + 1
print(contagem)

Resumo

  • d[chave] = valor cria o par se a chave é nova e troca o valor se ela já existe.
  • update() aplica vários pares de uma vez; a | b cria um dicionário novo (vale o valor da direita); |= muda o próprio.
  • del d[k] remove; d.pop(k) remove e devolve; d.pop(k, None) não dá erro; popitem() tira o último par; clear() esvazia.
  • Para contar: contagem[x] = contagem.get(x, 0) + 1. O contagem[x] += 1 sozinho dá KeyError na primeira vez.
  • Cuidado com chave digitada errado: não dá erro, vira chave nova.