Dicionários (dict) em Python: Guia Completo com Exemplos

Cansado de programar?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Projetos práticos

Projetos práticos voltados para o mercado de trabalho

Prática profissional

Formação moderna com foco na prática profissional

Download do Artigo

✅ Artigo atualizado em Setembro 2026 Novas seções sobre como percorrer um dicionário, verificar se uma chave existe e ordenar por valor, além de erros comuns com traceback e 8 exercícios resolvidos.

Resposta rápida

Um dicionário (dict, em inglês dictionary) é uma coleção de pares chave-valor: {'chave': 'valor'}. Você acessa um valor pela chave com d['chave'] ou d.get('chave') (que não quebra se a chave faltar), adiciona com d['nova'] = valor e percorre com for k, v in d.items().

1
2
3
4
5
6
aluno = {'nome': 'Ana', 'nota': 8.5}  # criar
print(aluno['nome'])                  # Ana
print(aluno.get('idade', 0))          # 0 (a chave não existe)
aluno['idade'] = 20                   # adicionar
for chave, valor in aluno.items():    # percorrer
    print(chave, valor)               # nome Ana / nota 8.5 / idade 20

Resumo em 30 segundos:

  • Chaves são únicas: atribuir a uma chave que já existe sobrescreve o valor.
  • Chaves precisam ser imutáveis (str, int, tuple); lista como chave gera TypeError.
  • d['x'] lança KeyError se a chave não existir; d.get('x') devolve None.
  • 'x' in d testa as chaves, não os valores (para valores, use in d.values()).
  • Desde o Python 3.7 o dict mantém a ordem de inserção, e a busca por chave é O(1).

Opa Dev!

Dicionários são a estrutura chave-valor mais importante do Python! Com lookups O(1), são perfeitos para mapeamentos, cache, contadores e configurações.

Neste guia completo, você vai aprender:

  • ✅ Criação e operações básicas
  • ✅ Métodos essenciais (get, update, pop, keys, values)
  • ✅ Como percorrer, verificar chaves e ordenar por valor
  • ✅ Casos de uso reais (cache, contadores, config)
  • ✅ dict vs defaultdict vs Counter - quando usar
  • ✅ Erros comuns e exercícios resolvidos

Garanto que você vai sair daqui um craque em Dicionários, combinado? Então já deixa o café pronto :coffee: e BORA!

Vá Direto ao Assunto…

Introdução

O que é um dicionário (dict) em Python? Um dicionário é uma coleção de pares chave-valor, escrita como {'chave': 'valor'}. Cada chave indexa um valor, a busca por chave é O(1) e, desde o Python 3.7, o dict mantém a ordem de inserção dos elementos.

Os dicionários são coleções de itens organizados em pares chave-valor, e desde o Python 3.7 seus elementos mantêm a ordem de inserção (a ordem em que foram adicionados). Eles são um dos tipos de dados nativos do Python, ao lado de listas, tuplas e sets, e a referência oficial está no tutorial do Python sobre dicionários.

Enquanto uma lista acessa os itens pela posição (lista[0]), o dicionário acessa pelo nome da chave (pessoa['nome']).

Seus elementos contém uma chave e valor, isto é:

  • Uma chave que vai servir para indexar (posicionar) determinado elemento no dicionário.
  • Um valor que contém… Bem, um valor :laughing: Este valor aceita diversos tipos: listas, outros dicionários, inteiros, strings e etc.

Sua sintaxe básica é: {'chave': 'valor'}. Utiliza-se {} para delimitar o dicionário e a chave é separada do valor por dois pontos :.

Exemplo de sua sintaxe:

1
2
3
dicio = {'chave': 'valor'}

print(type(dicio))

Quando utilizar type() e a saída for essa abaixo, pode ter certeza que é um dicionário!

1
<class 'dict'>

Criando dicionários

Agora vamos ver 6 maneiras de criar um mesmo dicionário!

O modo mais simples de criar um dicionário:

1
dicio_2 = {'primeiro': 1, 'segundo':  2, 'terceiro': 3}

Também podemos utilizar a função dict do próprio Python (built-in function), passando as chaves e valores como parâmetros:

1
dicio = dict(primeiro=1, segundo=2, terceiro=3)

Utilizando a função zip para concatenar a chave:valor em um elemento do objeto dict:

1
dicio_3 = dict(zip(['primeiro', 'segundo', 'terceiro'], [1, 2, 3]))

Utilizando uma lista de tuplas com itens simbolizando chave e valor em um objeto dict:

1
dicio_4 = dict([('primeiro', 1), ('segundo', 2), ('terceiro', 3)])

Com Dict Comprehensions!

Não sabe o que é? Nós temos um Post completissimo sobre Dict Comprehensions!

Veja como:

1
dicio_6 = {name: idx + 1 for idx, name in enumerate(('primeiro', 'segundo', 'terceiro'))}

Por mais estranho que pareça, podemos tentar transformar uma variável do tipo dicionário em dicionário.

1
dicio_5 = dict({'primeiro': 1, 'segundo':  2, 'terceiro': 3})

Todos esses exemplos tem o mesmo resultado, que esta sendo mostrado abaixo:

1
{'primeiro': 1, 'segundo': 2, 'terceiro': 3}

Métodos de dicionário (cheat-sheet)

Antes de mergulhar nos detalhes, aqui está um resumo rápido dos principais métodos e operações de dicionário em Python - o que cada um faz e o que retorna:

Método / operação O que faz Resultado
d.get(chave, padrão) Acessa o valor da chave sem erro se ela não existir Valor da chave, ou padrão (default None)
d.setdefault(chave, padrão) Retorna o valor da chave; se não existir, cria com padrão Valor existente ou recém-criado
d.keys() Devolve uma visão de todas as chaves dict_keys([...])
d.values() Devolve uma visão de todos os valores dict_values([...])
d.items() Devolve uma visão de pares (chave, valor) dict_items([(k, v), ...])
d.update(outro) Adiciona/atualiza chaves a partir de outro dict ou kwargs None (altera d no lugar)
d.pop(chave) Remove a chave e devolve seu valor Valor removido (KeyError se ausente)
del d[chave] Remove a chave do dicionário None (KeyError se ausente)

A seguir, cada um desses métodos é explicado em detalhe com exemplos.

Acessando itens

Para acessar um valor em um dicionário, use a chave entre colchetes (d[chave]) ou o método d.get(chave). A diferença: os colchetes lançam KeyError se a chave não existir, enquanto o .get() devolve None (ou um valor padrão) sem quebrar o programa.

Para acessar o valor de um dicionário podemos utilizar sua chave. Exemplo:

1
2
3
pessoa = {'nome': 'Pythonico', 'altura': 1.65, 'idade': 21}

print(pessoa['nome'])

Saída com o valor da chave especificada:

1
Pythonico

Dicionários também contam com um método chamado get() que fornecerá o mesmo resultado:

1
print(pessoa.get('nome'))

A saída será a mesma, o resultado: Pythonico

Uma coisa interessante sobre esse método é que você pode definir um valor default, para o caso da chave não ser encontrada, exemplo:

1
print(pessoa.get('peso', 'Chave não encontrada'))

Como não existe nenhuma chave chamada 'peso', ele retorna:

1
Chave não encontrada

:bulb: Estou construindo o Ebookr.ai, uma plataforma onde você cria ebooks profissionais com IA sobre qualquer assunto - do zero ao PDF pronto, com capas e infográficos gerados automaticamente. Dá uma olhada!

Obtendo chaves e valores

Se você deseja obter todas as chaves de um dicionário, use o método keys():

1
2
3
computador = {'CPU': 'Intel', 'RAM': '8gb', 'SSD': '250gb'}

print(computador.keys())

A saída é um objeto do tipo dict_keys que equivale a uma lista com todas as chaves:

1
dict_keys(['CPU', 'RAM', 'SSD'])

Para obter apenas os valores das chaves em seu dicionário:

1
2
3
notas = {'Mat': 5, 'Por': 7, 'His': 8}

print(notas.values())

A saída será uma lista com os valores de cada chave:

1
dict_values([5, 7, 8])

Percorrendo os elementos de um Dicionário

Podemos percorrer os elementos de um Dicionário a partir de suas chaves dict.keys() ou a partir de seus valores dict.values().

Percorrendo elementos com a função dict.keys():

1
2
3
4
computador = {'CPU': 'Intel', 'RAM': '8gb', 'SSD': '250gb'}

for chave in computador.keys():
  print(f'Chave = {chave} e Valor = {computador[chave]}')

A saída será:

1
2
3
Chave = CPU e Valor = Intel
Chave = RAM e Valor = 8gb
Chave = SSD e Valor = 250gb

Percorrendo elementos com a função dict.values():

1
2
3
4
notas = {'Mat': 5, 'Por': 7, 'His': 8}

for valor in notas.values():
    print(f'Valor: {valor}')

A saída será:

1
2
3
Valor: 5
Valor: 7
Valor: 8

Percorrendo as chaves e valores de um Dicionário

Uma maneira de obter chaves e valores é utilizando o método dict.items().

Veja como:

1
2
3
frutas = {'pera': 10, 'uva': 2, 'maça': 55}

print(frutas.items())

A saída equivale a uma lista com elementos organizados em tuplas, sendo:

  • O primeiro elemento da tupla a chave do dicionário e
  • O segundo elemento, o valor presente naquela chave.

Veja:

1
dict_items([('pera', 10), ('uva', 2), ('maça', 55)])

Podemos acessar esses valores utilizando o loop for, para percorrer esses dados:

1
2
for chave, valor in frutas.items():
    print(f"Chave = {chave} - Valor = {valor}")

A saída será:

1
2
3
Chave = pera - Valor = 10
Chave = uva - Valor = 2
Chave = maça - Valor = 55

Uma maneira segura de acessar um elemento de um dicionário é verificando primeiro se a chave existe.

Exemplo:

1
2
3
4
5
6
7
8
9
dicio_cores = {'amarelo': 10, 'vermelho': 2, 'cinza': 55}

# Verificando se chave existe
if 'amarelo' in dicio_cores:
    print(f"Como a cor desejada existe: {dicio_cores['amarelo']}")

# Verificando se valor existe
if 10 in dicio_cores.values():
    print('O valor desejado existe')

A saída será:

1
2
Como a cor desejada existe: 10
O valor desejado existe

Como percorrer um dicionário em Python

Existem três jeitos de percorrer um dicionário com o for, e a escolha depende do que você precisa dentro do laço (se ainda não domina o for, veja nosso guia de estruturas de repetição no Python):

Forma O que o for entrega Quando usar
for k in d ou for k in d.keys() Só as chaves Precisa apenas dos nomes das chaves
for v in d.values() Só os valores Somar, contar ou filtrar valores
for k, v in d.items() Tuplas (chave, valor) Precisa dos dois (o caso mais comum)
for i, (k, v) in enumerate(d.items()) Posição + chave + valor Numerar a saída

Percorrer o dicionário diretamente (for k in d) é o mesmo que usar d.keys(). Veja também como numerar os itens com enumerate():

1
2
3
4
5
6
7
estoque = {'caneta': 10, 'caderno': 4, 'mochila': 1}

for produto in estoque:  # igual a estoque.keys()
    print(produto)

for posicao, (produto, qtd) in enumerate(estoque.items(), start=1):
    print(f'{posicao}. {produto}: {qtd}')

Saída:

1
2
3
4
5
6
caneta
caderno
mochila
1. caneta: 10
2. caderno: 4
3. mochila: 1

Os itens saem na ordem de inserção. Só não adicione nem remova chaves durante o laço: isso gera RuntimeError (veja em Erros comuns).

Como verificar se uma chave existe no dicionário

Use o operador in (ou not in). Ele devolve True ou False e olha somente as chaves. Para procurar um valor, aplique o in em d.values():

1
2
3
4
5
6
7
8
9
10
usuario = {'nome': 'Ana', 'email': '[email protected]'}

print('email' in usuario)        # True
print('telefone' in usuario)     # False
print('telefone' not in usuario) # True
print('Ana' in usuario)          # False: o in olha as chaves
print('Ana' in usuario.values()) # True

telefone = usuario.get('telefone', 'não informado')
print(telefone)

Saída:

1
2
3
4
5
6
True
False
True
False
True
não informado

Regra prática: use if chave in d: quando a lógica muda conforme a chave existe ou não, e d.get(chave, padrão) quando você só quer o valor com um substituto. O in em dicionário é O(1), enquanto in d.values() precisa varrer todos os valores (O(n)).

Adicionando e atualizando itens

A maneira mais simples de adicionar um item a um dicionario é criar uma nova chave e atribuir um valor. Assim:

1
2
3
4
5
dicio = {'nome': 'Erick'}

dicio['idade'] = 20

print(dicio)

Resultando na adição da chave e valor especificada acima:

1
{'nome': 'Erick', 'idade': 20}

O método update() tanto pode criar, como atualizar dados:

1
2
3
4
5
6
7
8
9
10
dicio = {'nome': 'Erick'}

# Atualiza o elemento de chave 'nome'
dicio.update({'nome':'Matheus'})

# Cria os elementos de chave 'idade' e 'tamanho'
dicio.update({'idade':18})
dicio.update(tamanho=1.60)

print(dicio)

Saída:

1
{'nome': 'Matheus', 'idade': 18, 'tamanho': 1.6}

Está curtindo esse conteúdo? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

Excluindo elementos no dicionário

Você pode excluir um elemento do dicionário com a keyword del do Python, especificando sua chave:

1
2
3
4
5
pessoa = {'nome': 'Matheus', 'idade': 18, 'tamanho': 1.60}

del pessoa['tamanho']

print(pessoa)

Resultando na exclusão do dado especificado:

1
{'nome': 'Matheus', 'idade': 18}

Excluindo e retornando o elemento excluído

O método pop() remove o item cujo a chave foi especificada:

1
2
3
4
5
6
sacola = {'maça': 2, 'ovos': 6, 'farinha': 2}

ovos = sacola.pop('ovos')

print(ovos)
print(sacola)

Saída:

1
2
6
{'maça': 2, 'farinha': 2}

Veja que o dicionário resultante não possui mais a chave ['ovos']

Excluindo último item

O método popitem() também remove o último elemento do dicionário.

Contudo, diferente do método pop() que apenas retorna o valor daquele elemento, popitem() retorna o elemento todo, contendo chave e valor.

Veja usando o mesmo exemplo do método pop():

1
2
3
4
5
6
sacola = {'maça': 2, 'ovos': 6, 'farinha': 2}

farinha = sacola.popitem()

print(farinha)
print(sacola)

Veja que o retorno foi uma tupla e o último item foi removido:

1
2
('farinha', 2)
{'maça': 2, 'ovos': 6}

Limpando dicionário

Uma maneira de esvaziar um dicionário é utilizando o método clear(), dessa forma:

1
2
3
4
dicio = {'nome': 'F9', 'motor': 'v8', 'ano': 2019}
dicio.clear()

print(dicio)

O retorno é um dicionário vazio: {}.

Copiando Dicionário

Em Python, você não pode simplesmente digitar dict1 = dict2 para copiar um dicionário.

Dessa forma você esta apenas copiando a referência do dict1 ao dict2.

A maneira correta de criar uma cópia do dicionário é utilizando o método copy(), assim:

1
2
3
4
5
6
dicio = {"operacao": "web scraping", "dados": 250}

copia = dicio.copy()

print(copia)
print(dicio)

Resultando na cópia exata do dicionário

1
2
{'operacao': 'web scraping', 'dados': 250}
{'operacao': 'web scraping', 'dados': 250}

O método dict.setdefault()

O método dict.setdefault() retorna o valor da chave especificada, e, caso a chave não exista, a cria com o valor especificado.

Vamos ao exemplo:

1
2
3
4
5
6
dicio = {'coleta': 'scrapy', 'dados': 200}

set_dados = dicio.setdefault('dados')

print(set_dados)
print(dicio)

Como a chave dados existe, ela é retornada:

1
2
200
{'coleta': 'scrapy', 'dados': 200}

Agora vamos adicionar apenas a chave sem valor, e outro com chave e valor:

1
2
3
4
5
6
7
8
dicio = {'coleta': 'scrapy', 'dados': 200}

set_data = dicio.setdefault('data')
set_teste = dicio.setdefault('teste', 1)

print(set_data)
print(set_teste)
print(dicio)

A saída resulta em:

1
2
3
None
1
{'coleta': 'scrapy', 'dados': 200, 'data': None, 'teste': 1}

O set_data que teve apenas atribuída uma chave, teve seu valor criado como None, enquanto set_teste teve o valor adicionado.

Criando Dicionários a partir de lista de valores

Com o método dict.fromkeys() é possível criar um dicionário a partir de uma lista de chaves e um valor, que será usado em todas as chaves.

Veja o exemplo:

1
2
3
4
5
6
chaves = ['chave1', 'chave2', 'chave3']
valor = 0

dicio = dict.fromkeys(chaves , valor)

print(dicio)

Veja que o valor 0 foi atribuído em todas as chaves:

1
{'chave1': 0, 'chave2': 0, 'chave3': 0}

Operador de “desempacotamento”

O Python introduziu em sua linguagem um operador de “unpacking”, ou operador de desempacotamento.

Para utilizar esse operador, devemos usar dois asteriscos antes da variável que vai ser descontruída (**variavel).

Pode ser utilizado em tuplas, listas e em nossos queridos dicionários.

No caso do Dicionário, o que ele faz é desconstruir cada elemento do dicionário em chave e valor, tentando casar o nome do argumento da função com a chave do dicionário.

Ficou confuso? :confused: Vamos ao exemplo!

Suponha a seguinte função:

1
2
def funcao(argumento):
    print(argumento)

Agora vamos chamá-la duas vezes, uma sem o operador de desempacotamento e outra com ele:

1
2
3
4
dicionario = {'argumento': 1}

funcao(dicionario)
funcao(**dicionario)

Agora veja a saída de cada um:

1
2
{'argumento': 1}
1

Na primeira chamada, sem o operador, a saída foi apenas o print daquilo que foi passado. No caso, um dicionário.

Já na segunda, o operador fez com que a função tentasse “encaixar” a chave argumento do dicionário (de valor 1) com o argumento da função.

Dessa forma, apenas o valor foi printado!

Dicionários como args e kwargs

Como vimos aqui em cima, dicionários podem ser passados como valores para funções.

Além disso, podemos usar o operador de desempacotamento para casar as chaves do dicionário com os argumentos da função:

1
2
3
4
5
6
7
8
9
regulagem = {'max': 10, 'meio': 5, 'min': 0}

def funcao(max, meio, min):
    print(max)
    print(meio)
    print(min)


funcao(**regulagem)

Resultando em:

1
2
3
10
5
0

Se caso você desconheça as chaves de um dicionário, basta adicionar em sua função o atributo kwargs (Keyword Arguments ou Argumentos Nomeados).

O atributo kwargs recebe todos os argumento que tenham sido passados com nome.

Exemplo: funcao(arg=1). Nesse caso, arg é um Argumento Nomeado e pode ser acessado pela variável kwargs.

Percorrendo o kwargs temos acesso às chaves, onde podemos, portanto, buscar os valores que desejamos através do método .get().

Veja o exemplo:

1
2
3
4
5
6
7
8
9
# Definição da Função recebendo kwargs
def funcao(**kwargs):
    # Percorrendo argumento nomeados
    for chave in kwargs:
        print(f"Acessando Chave '{chave}', valor = {kwargs.get(chave)}")

regulagem = {'max': 10, 'meio': 5, 'min': 0}

funcao(**regulagem)

Saída impressa pela função:

1
2
3
Acessando Chave 'max', valor = 10
Acessando Chave 'meio', valor = 5
Acessando Chave 'min', valor = 0

Já o argumento args possui os Argumentos Não-Nomeados.

Se necessario pegar apenas as chaves do dicionário, podemos utilizar args para isso e chamando a função passando um asterisco em nosso dicionário, da seguinte maneira:

1
2
3
4
5
def funcao(*args):
    for chave in args:
        print(chave)

funcao(*regulagem)

Veja que saída contém apenas as chaves:

1
2
3
max
meio
min

Juntando dicionários

Para juntar dois dicionários você tem duas opções: o operador de merge | (Python 3.9+) ou o desempacotamento {**a, **b} (qualquer versão). Em ambos, se a mesma chave existir nos dois, o valor do dicionário da direita prevalece.

Desempacotamento com **

Como o operador de desempacotamento desconstrói um dicionário em chave e valor, podemos utilizá-lo para juntar dicionários, da seguinte forma:

1
2
3
4
5
6
7
regulagem = {'max': 10, 'meio': 5, 'min': 0}
extra = {'passo': 2}

# Junção de dicionários com **
juncao_dicio = {**regulagem, **extra}

print(juncao_dicio)

Saída:

1
{'max': 10, 'meio': 5, 'min': 0, 'passo': 2}

Operador de merge | e |= (Python 3.9+)

A partir do Python 3.9 (PEP 584) existe uma forma mais limpa e legível de unir dicionários: o operador |. Ele cria um novo dicionário com a junção dos dois, sem alterar os originais:

1
2
3
4
5
6
7
regulagem = {'max': 10, 'meio': 5, 'min': 0}
extra = {'passo': 2}

# Junção com o operador | (cria um novo dict)
juncao_dicio = regulagem | extra

print(juncao_dicio)

Saída:

1
{'max': 10, 'meio': 5, 'min': 0, 'passo': 2}

Já o operador |= faz o merge no lugar (in-place), atualizando o dicionário da esquerda - é o equivalente a um regulagem.update(extra):

1
2
3
4
5
6
7
regulagem = {'max': 10, 'meio': 5, 'min': 0}
extra = {'passo': 2}

# Merge in-place: atualiza 'regulagem'
regulagem |= extra

print(regulagem)

Saída:

1
{'max': 10, 'meio': 5, 'min': 0, 'passo': 2}

Como ordenar um dicionário por valor

O dicionário não tem um método sort(). O caminho é passar os itens para a função sorted() com um key que devolve o valor de cada par (item[1]). O resultado é uma lista de tuplas, que você pode transformar de volta em dict (a nova ordem é mantida). O key costuma ser uma função lambda, e a documentação oficial de ordenação traz mais variações.

1
2
3
4
5
6
7
8
9
10
11
vendas = {'Carla': 580, 'Ana': 350, 'Bruno': 120}

# Crescente pelo valor (item[1])
print(sorted(vendas.items(), key=lambda item: item[1]))

# Decrescente, reconstruindo um dict
ranking = dict(sorted(vendas.items(), key=lambda item: item[1], reverse=True))
print(ranking)

# Por chave (ordem alfabética)
print(dict(sorted(vendas.items())))

Saída:

1
2
3
[('Bruno', 120), ('Ana', 350), ('Carla', 580)]
{'Carla': 580, 'Ana': 350, 'Bruno': 120}
{'Ana': 350, 'Bruno': 120, 'Carla': 580}

Repare que sorted() não altera o dicionário original: ele devolve um objeto novo. Para pegar só os primeiros colocados, fatie a lista antes de converter: sorted(...)[:3].

Esses casos de uso reais são só uma amostra: na Jornada Python você aplica dicionários em projetos completos, como scraping de dados financeiros e automação de planilhas:

Casos de Uso Reais

1. Cache Simples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Cache de resultados de funções pesadas
cache = {}

def processar_dados(user_id):
    if user_id in cache:
        print(f"Cache hit para {user_id}!")
        return cache[user_id]

    # Simular processamento pesado
    result = f"Dados processados para {user_id}"
    cache[user_id] = result
    return result

processar_dados(123)  # Processa
processar_dados(123)  # Retorna do cache!

2. Contador de Frequências

1
2
3
4
5
6
7
8
9
# Contar palavras em texto
texto = "python é ótimo python é rápido"
palavras = texto.split()

contador = {}
for palavra in palavras:
    contador[palavra] = contador.get(palavra, 0) + 1

print(contador)  # {'python': 2, 'é': 2, 'ótimo': 1, 'rápido': 1}

3. Agrupar Dados por Chave

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Agrupar usuários por cidade
users = [
    {'name': 'Alice', 'city': 'SP'},
    {'name': 'Bob', 'city': 'RJ'},
    {'name': 'Charlie', 'city': 'SP'}
]

by_city = {}
for user in users:
    city = user['city']
    if city not in by_city:
        by_city[city] = []
    by_city[city].append(user['name'])

print(by_city)  # {'SP': ['Alice', 'Charlie'], 'RJ': ['Bob']}

4. Configurações de Aplicação

1
2
3
4
5
6
7
8
9
10
11
12
# Configurações com valores padrão
default_config = {
    'debug': False,
    'port': 8000,
    'host': 'localhost'
}

user_config = {'port': 9000}

# Mesclar configs (user sobrescreve default)
config = {**default_config, **user_config}
print(config)  # {'debug': False, 'port': 9000, 'host': 'localhost'}

dict vs defaultdict vs Counter

Comparação Rápida

Tipo Quando usar Vantagem
dict Geral Padrão, versátil
defaultdict Chaves inexistentes Auto-inicialização
Counter Contagem Métodos específicos
OrderedDict Ordem (< 3.7) Python 3.7+ dicts já mantém ordem

Exemplos Práticos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from collections import defaultdict, Counter

# dict: Manual
contador = {}
for letra in 'mississippi':
    contador[letra] = contador.get(letra, 0) + 1

# defaultdict: Auto-inicializa (mais limpo!)
contador = defaultdict(int)
for letra in 'mississippi':
    contador[letra] += 1  # Não precisa checar se existe

# Counter: Especializado (mais simples!)
contador = Counter('mississippi')
print(contador.most_common(2))  # [('i', 4), ('s', 4)]

Quando Usar Cada Um?

✅ Use dict quando:

  • Mapeamento geral chave-valor
  • Precisa controlar inicialização
  • API pública (mais conhecido)

✅ Use defaultdict quando:

  • Muitas chaves inexistentes
  • Agrupar/agregar dados
  • Evitar .get(key, default)

✅ Use Counter quando:

  • Contar frequências
  • Operações matemáticas (adição, subtração)
  • .most_common() necessário

Performance: O(1) Lookups

Buscar uma chave em um dicionário é O(1) (tempo constante), enquanto o in em uma lista é O(n) - precisa varrer os elementos um a um. Vamos medir isso com timeit, que executa cada busca milhares de vezes e tira a média:

1
2
3
4
5
6
7
8
9
10
11
import timeit

lista = list(range(100_000))
dict_data = {i: i for i in range(100_000)}

# Mede a busca pelo elemento final (pior caso da lista)
t_lista = timeit.timeit(lambda: 99999 in lista, number=10_000)
t_dict = timeit.timeit(lambda: 99999 in dict_data, number=10_000)

print(f"Lista (O(n)): {t_lista / 10_000 * 1e6:.1f} us por busca")
print(f"Dict  (O(1)): {t_dict / 10_000 * 1e6:.4f} us por busca")

Saída (varia conforme a máquina):

1
2
Lista (O(n)): 464.0 us por busca
Dict  (O(1)): 0.0795 us por busca

Resultado: para essa busca, o dict foi milhares de vezes mais rápido que a lista. E a diferença só cresce com o tamanho da coleção: na lista o tempo aumenta junto com n, enquanto no dict permanece praticamente constante.

Erros comuns

Estes são os erros que mais aparecem com dicionários, com a mensagem real que o Python mostra.

Acessar uma chave que não existe (KeyError)

1
2
aluno = {'nome': 'Ana'}
print(aluno['idade'])
1
KeyError: 'idade'

Correção: use aluno.get('idade') (devolve None) ou aluno.get('idade', 0) para ter um valor padrão, ou teste antes com if 'idade' in aluno:.

Usar uma lista como chave (TypeError: unhashable type)

1
coordenadas = {[10, 20]: 'casa'}
1
TypeError: unhashable type: 'list'

Correção: chaves precisam ser imutáveis. Troque a lista por uma tupla: coordenadas = {(10, 20): 'casa'} e acesse com coordenadas[(10, 20)].

Alterar o dicionário enquanto percorre (RuntimeError)

1
2
3
4
5
estoque = {'maçã': 0, 'pera': 3, 'uva': 0}

for fruta in estoque:
    if estoque[fruta] == 0:
        del estoque[fruta]
1
RuntimeError: dictionary changed size during iteration

Correção: percorra uma cópia das chaves ou crie um dicionário novo com uma dict comprehension:

1
2
3
4
5
6
7
8
9
10
11
12
estoque = {'maçã': 0, 'pera': 3, 'uva': 0}

for fruta in list(estoque):  # percorre uma cópia das chaves
    if estoque[fruta] == 0:
        del estoque[fruta]

print(estoque)

# Ou crie um dict novo só com o que interessa:
estoque = {'maçã': 0, 'pera': 3, 'uva': 0}
estoque = {fruta: qtd for fruta, qtd in estoque.items() if qtd > 0}
print(estoque)
1
2
{'pera': 3}
{'pera': 3}

Acessar keys() por índice (TypeError: not subscriptable)

1
2
cores = {'azul': 1, 'verde': 2}
print(cores.keys()[0])
1
TypeError: 'dict_keys' object is not subscriptable

Correção: dict_keys é uma visão, não uma lista. Converta antes (list(cores.keys())[0]) ou pegue a primeira chave com next(iter(cores)). As duas formas devolvem 'azul'.

Exercícios resolvidos

Tente resolver cada exercício antes de abrir a solução. Todos os códigos foram executados e as saídas conferidas.

Exercício 1. Crie um dicionário precos com café (12.5), pão (0.8) e leite (5.9). Mostre o preço do café, adicione manteiga (9.9) e atualize o pão para 1.0.

Ver solução
1
2
3
4
5
6
precos = {'café': 12.5, 'pão': 0.8, 'leite': 5.9}

print(precos['café'])
precos['manteiga'] = 9.9
precos['pão'] = 1.0
print(precos)

Saída:

1
2
12.5
{'café': 12.5, 'pão': 1.0, 'leite': 5.9, 'manteiga': 9.9}

A mesma sintaxe d[chave] = valor cria a chave se ela não existe e atualiza se já existe. Por isso 'pão' continua na mesma posição.

Exercício 2. Conte quantas vezes cada letra aparece na palavra 'banana', guardando o resultado em um dicionário.

Ver solução
1
2
3
4
5
6
7
palavra = 'banana'
contagem = {}

for letra in palavra:
    contagem[letra] = contagem.get(letra, 0) + 1

print(contagem)

Saída: {'b': 1, 'a': 3, 'n': 2}

O get(letra, 0) devolve 0 na primeira vez que a letra aparece, evitando o KeyError. Em código real, Counter('banana') faz o mesmo.

Exercício 3. Dado notas = {'Ana': 8.5, 'Bruno': 6.0, 'Carla': 7.0, 'Diego': 4.5}, mostre apenas os alunos aprovados (nota maior ou igual a 7).

Ver solução
1
2
3
4
5
notas = {'Ana': 8.5, 'Bruno': 6.0, 'Carla': 7.0, 'Diego': 4.5}

for nome, nota in notas.items():
    if nota >= 7:
        print(f'{nome} aprovado(a) com {nota}')

Saída:

1
2
Ana aprovado(a) com 8.5
Carla aprovado(a) com 7.0

O items() entrega chave e valor juntos, então não é preciso fazer notas[nome] dentro do laço.

Exercício 4 (questão de prova). Qual é a saída do código abaixo?

1
2
3
4
d = {'a': 1, 'b': 2}
d['a'] = 10
d['c'] = 3
print(len(d), d['a'])

a) 3 10
b) 4 10
c) 3 1
d) KeyError

Ver solução

Resposta: a). Saída: 3 10

Chaves são únicas: d['a'] = 10 sobrescreve o valor de 'a' em vez de criar outra chave, e d['c'] = 3 adiciona uma chave nova. O dicionário termina com 3 chaves e d['a'] vale 10.

Exercício 5 (questão de prova). Qual dos valores abaixo não pode ser usado como chave de um dicionário?

a) 'nome'
b) 42
c) (1, 2)
d) [1, 2]

Ver solução

Resposta: d). Testando os quatro:

1
2
3
4
5
6
7
8
chaves = ['nome', 42, (1, 2), [1, 2]]

for chave in chaves:
    try:
        {chave: 'ok'}
        print(repr(chave), 'pode ser chave')
    except TypeError as erro:
        print(repr(chave), '->', erro)

Saída:

1
2
3
4
'nome' pode ser chave
42 pode ser chave
(1, 2) pode ser chave
[1, 2] -> unhashable type: 'list'

Chaves precisam ser imutáveis (hashable). Strings, números e tuplas são; listas podem mudar depois de criadas, por isso o Python as recusa.

Exercício 6. Dado vendas = {'jan': 1200, 'fev': 800, 'mar': 1500, 'abr': 950}, mostre os 2 meses com mais vendas, do maior para o menor.

Ver solução
1
2
3
4
5
6
vendas = {'jan': 1200, 'fev': 800, 'mar': 1500, 'abr': 950}

top2 = sorted(vendas.items(), key=lambda item: item[1], reverse=True)[:2]

for mes, valor in top2:
    print(mes, valor)

Saída:

1
2
mar 1500
jan 1200

O key=lambda item: item[1] ordena pelo valor, o reverse=True inverte para decrescente e o fatiamento [:2] pega os dois primeiros.

Exercício 7. Você tem uma lista de dicionários com pedidos. Calcule o total gasto por cliente.

1
2
3
4
5
pedidos = [
    {'cliente': 'Ana', 'valor': 50},
    {'cliente': 'Bruno', 'valor': 30},
    {'cliente': 'Ana', 'valor': 20},
]
Ver solução
1
2
3
4
5
6
total_por_cliente = {}
for pedido in pedidos:
    nome = pedido['cliente']
    total_por_cliente[nome] = total_por_cliente.get(nome, 0) + pedido['valor']

print(total_por_cliente)

Saída: {'Ana': 70, 'Bruno': 30}

Cada item da lista é um dicionário, então pedido['cliente'] lê o nome. O dicionário de totais usa o nome como chave e acumula com get(nome, 0). Esse formato (lista de dicionários) é exatamente o que você recebe ao ler um JSON de uma API.

Exercício 8. É possível colocar um dicionário dentro de outro? Usando o dicionário escola abaixo, mostre o professor da turma_b e o total de alunos da escola.

1
2
3
4
escola = {
    'turma_a': {'professor': 'Marcos', 'alunos': 28},
    'turma_b': {'professor': 'Luiza', 'alunos': 31},
}
Ver solução
1
2
3
4
print(escola['turma_b']['professor'])

total = sum(turma['alunos'] for turma in escola.values())
print(total)

Saída:

1
2
Luiza
59

Sim: valores de dicionário podem ser de qualquer tipo, inclusive outro dicionário. Para acessar, encadeie as chaves (escola['turma_b']['professor']).

Quer praticar dicionários, listas e funções construindo projetos guiados do zero? Conheça o nosso curso de Python completo, a Jornada Python.

Conclusão

Neste guia completo sobre Dicionários, você aprendeu:

✅ Operações básicas - Criar, acessar, modificar
✅ Métodos essenciais - get, update, pop, keys, values, items
✅ Casos de uso reais - Cache, contadores, agrupamentos, config
✅ dict vs defaultdict vs Counter - Quando usar cada um
✅ Performance - Lookups O(1) vs listas O(n)

Principais lições:

  • Dicts têm busca O(1) - instantâneo!
  • Use .get(key, default) para evitar KeyError
  • Python 3.7+ mantém ordem de inserção
  • defaultdict simplifica código com muitas chaves novas
  • Counter é especializado para contagem

Próximos passos:

Nesse Post vimos do básico ao avançado sobre Dicionários!

Se ficou com alguma dúvida, fique à vontade para deixar um comentário no box aqui embaixo! Será um prazer te responder! :wink:

Perguntas frequentes

O que é um dicionário (dict) em Python?

Um dicionário (dict) em Python é uma coleção de pares chave-valor com sintaxe {'chave': 'valor'}. Cada chave indexa um valor e o acesso é O(1). Desde o Python 3.7 ele mantém a ordem de inserção.

Como acessar um valor de dicionário com segurança em Python?

Use o método .get(): pessoa.get('peso', 'padrão') retorna o valor da chave ou o default informado, sem lançar KeyError quando a chave não existe - diferente de acessar com colchetes pessoa['peso'].

Dicionário em Python é ordenado?

Sim. Desde o Python 3.7 o dict mantém a ordem de inserção das chaves: ao percorrê-lo, os itens saem na ordem em que foram adicionados. Antes da 3.7 era preciso usar OrderedDict para garantir essa ordem.

Como juntar dois dicionários em Python?

A partir do Python 3.9 use o operador de merge: a | b cria um novo dict e a |= b atualiza no lugar. Em versões anteriores, use o desempacotamento {**a, **b}. Em conflito de chaves, o dict da direita vence.

O que é dict comprehension em Python?

É uma forma concisa de criar dicionários em uma linha, como {k: v for k, v in itens}. Equivale a um laço for que monta o dict, porém mais legível e rápido de escrever.

Como verificar se uma chave existe em um dicionário Python?

Use o operador in: 'email' in usuario devolve True se a chave existir e False se não existir (not in faz o contrário). O in testa apenas as chaves; para procurar um valor use 'Ana' in usuario.values(). Se o objetivo é ler o valor, usuario.get('email', 'padrão') já trata a ausência sem KeyError.

Como ordenar um dicionário por valor em Python?

Use sorted() nos itens com uma função key que pega o valor: sorted(d.items(), key=lambda item: item[1]) devolve uma lista de tuplas em ordem crescente. Acrescente reverse=True para ordem decrescente e envolva em dict() para voltar a ter um dicionário, que mantém a nova ordem desde o Python 3.7. Para ordenar por chave, basta dict(sorted(d.items())).

Quais tipos podem ser chave de um dicionário em Python?

Só objetos imutáveis (hashable) podem ser chave: str, int, float, bool e tuplas que contenham apenas imutáveis. Listas, dicionários e sets não podem, e tentar usá-los gera TypeError: unhashable type: 'list'. Em questão de prova, entre ‘nome’, 42, (1, 2) e [1, 2], a única chave inválida é a lista [1, 2]. Os valores, por outro lado, podem ser de qualquer tipo.

Começe agora sua Jornada na Programação!

Não deixe para amanhã o sucesso que você pode começar a construir hoje!

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.