Como evitar KeyError usando defaultdict no Python

Publicado em: 30/03/2026
Tempo de leitura: 9 minutos

Você já tentou acessar uma chave em um dicionário e se deparou com aquele erro vermelho interrompendo seu script? O erro KeyError é um dos 7 erros mais comuns em python e ocorre quando o interpretador tenta buscar uma informação que simplesmente não existe no mapeamento. Para quem está aprendendo logica de programação com python, lidar com essas exceções pode parecer frustrante, mas existe uma ferramenta poderosa na biblioteca padrão chamada defaultdict que resolve esse problema de forma elegante e eficiente.

Os dicionários tradicionais em Python são estruturas de dados incríveis, mas eles são rigorosos. Se você pedir por “idade” em um dicionário que só tem “nome”, o Python lançará um KeyError. Embora possamos usar blocos try-except em python para capturar essa falha, o código acaba ficando poluído e difícil de ler quando precisamos fazer muitas verificações. É aqui que entra o módulo collections, oferecendo o defaultdict como uma alternativa inteligente para manter seu fluxo de trabalho limpo e funcional.

O que é o KeyError e por que ele acontece?

O KeyError é uma exceção levantada quando você tenta acessar uma chave que não foi mapeada dentro de um objeto do tipo dict. No Python, os dicionários funcionam como tabelas de dispersão (hash tables). Cada chave deve ser única e estar presente para que o valor correspondente seja retornado. Quando o programa faz uma requisição por algo inexistente, o Python interrompe a execução para evitar que o erro se propague de forma silenciosa e cause comportamentos imprevistos no futuro.

Imagine que você está contando a frequência de palavras em um texto. Se a palavra “Python” ainda não foi adicionada ao seu contador, tentar incrementar o valor dela (contador['Python'] += 1) causará um erro imediato, pois o Python tenta primeiro ler o valor atual para somar 1, mas não encontra nada. Para entender melhor como os dados são organizados, vale a pena conferir a diferença entre lista tupla conjunto e dicionario.

Conhecendo o potencial do defaultdict no Python

O defaultdict é uma subclasse da classe de dicionário padrão (dict). Ele faz parte do módulo collections, que fornece alternativas especializadas para os tipos de dados python nativos. A grande diferença é que o defaultdict nunca levanta um KeyError. Em vez disso, ele fornece um valor padrão para qualquer chave que ainda não existe.

Para funcionar, o defaultdict recebe um argumento chamado default_factory. Esse argumento deve ser uma função ou um “callable” que retorna o valor inicial que você deseja atribuir. Por exemplo, se você quer que todas as chaves novas comecem com o número zero, você passa a função int como fábrica. Se prefere listas vazias, passa list. Isso torna a manipulação de dicionários no python muito mais fluida.

O uso do defaultdict é recomendado pela própria documentação oficial do Python como uma forma eficiente de simplificar a inicialização de coleções complexas.

Como evitar KeyError usando defaultdict no Python na prática

A forma mais comum de evitar o erro é importar o módulo e definir qual será o comportamento padrão do seu dicionário. Vamos ver um exemplo simples onde contamos a ocorrência de itens em uma lista sem precisar verificar se a chave existe a cada iteração.

Python
from collections import defaultdict

# Definindo um valor padrão do tipo inteiro (começa em 0)
contador = defaultdict(int)

frutas = ['maçã', 'banana', 'maçã', 'laranja', 'banana', 'maçã']

for fruta in frutas:
    # Não precisamos verificar 'if fruta in contador'
    contador[fruta] += 1

print(dict(contador)) 
# Saída: {'maçã': 3, 'banana': 2, 'laranja': 1}

No código acima, quando o loop encontra “maçã” pela primeira vez, o defaultdict percebe que a chave não existe, chama a função int() (que retorna 0), cria a chave com esse valor e depois soma 1. Tudo isso acontece nos bastidores, eliminando a necessidade de usar o operador in no python ou o método .get().

Trabalhando com listas e agrupamentos de dados

Outro cenário muito frequente onde o defaultdict brilha é no agrupamento de informações. Imagine que você tem uma lista de estados e cidades e quer organizar as cidades por estado. Usando um dicionário comum, você teria que criar uma lista vazia manualmente para cada novo estado encontrado.

Python
from collections import defaultdict

cidades_por_estado = defaultdict(list)

dados = [('SP', 'São Paulo'), ('RJ', 'Rio de Janeiro'), ('SP', 'Campinas')]

for uf, cidade in dados:
    cidades_por_estado[uf].append(cidade)

print(cidades_por_estado['SP']) # ['São Paulo', 'Campinas']
print(cidades_por_estado['MG']) # Retorna [] em vez de erro!

Note que, ao tentar acessar ‘MG’, o Python não trava. Ele simplesmente cria uma lista vazia e a retorna. Essa característica é valiosa para quem trabalha com python para automação, pois garante que o script não pare por falta de dados esperados em uma planilha ou banco de dados.

Diferenças entre dict.get(), dict.setdefault() e defaultdict

Para um desenvolvedor sênior, saber escolher a ferramenta certa é essencial. Existem três formas principais de lidar com chaves ausentes:

MétodoComportamentoMelhor caso de uso
dict.get(key, default)Retorna um valor padrão mas não altera o dicionário.Verificações rápidas e ocasionais.
dict.setdefault(key, default)Retorna o valor e insere o padrão se a chave não existir.Scripts pequenos onde você não quer importar módulos.
defaultdictCria automaticamente a chave com o valor da fábrica.Loops grandes, contadores e agrupamentos constantes.

Embora o get() seja útil, ele exige que você repita o valor padrão toda vez que chamar a chave. O defaultdict centraliza essa lógica na criação do objeto, seguindo o princípio DRY (Don’t Repeat Yourself), muito prezado na comunidade Python Software Foundation.

Performance e eficiência de memória

Em termos de desempenho, o defaultdict é extremamente veloz. Como a lógica de criação da chave é tratada em nível de C (a linguagem em que o CPython é escrito), ela tende a ser mais rápida do que escrever blocos if/else manuais dentro de um loop for em python. No entanto, é preciso ter atenção: o defaultdict cria entradas para cada consulta. Se você testar a existência de milhares de chaves que não existem, seu dicionário crescerá em memória, mesmo que você nunca atribua valores manualmente a elas.

Para tarefas de contagem específicas, o Python oferece ainda o collections counter, que é uma especialização ainda maior do defaultdict focada exclusivamente em contar elementos de forma performática.

Casos de uso avançados com funções personalizadas

Você não está limitado a usar int, list ou set. O parâmetro default_factory aceita qualquer função que não exija argumentos. Você pode usar uma lambda python para definir valores iniciais arbitrários, como uma string padrão ou um número fixo diferente de zero.

Python
from collections import defaultdict

# Iniciando todas as chaves com o valor 100
estoque = defaultdict(lambda: 100)

estoque['canetas'] -= 5
print(estoque['canetas']) # 95
print(estoque['borrachas']) # 100 (criado na hora)

Essa flexibilidade permite que o desenvolvedor crie estruturas de dados complexas, como dicionários aninhados (dicionários dentro de dicionários), o que é muito comum ao consumir json no python vindo de APIs web.

Boas práticas ao utilizar o defaultdict

Apesar de sua utilidade, o defaultdict deve ser usado com discernimento. Um erro comum é esquecer que ele sempre cria chaves novas. Se você passar esse dicionário para uma função que apenas deveria ler dados, ela pode acabar “sujando” o objeto com chaves vazias acidentalmente. Em muitos casos, é recomendável converter o defaultdict de volta para um dict comum (usando dict(meu_defaultdict)) antes de passá-lo para outras partes do sistema.

Além disso, sempre documente o comportamento esperado. Outros desenvolvedores que lerem seu código precisam saber que as chaves estão sendo geradas automaticamente para não serem pegos de surpresa por um comportamento que parece “mágico” à primeira vista.

Conclusão sobre o tratamento de chaves no Python

Dominar o defaultdict é um passo importante para sair do nível básico e entrar no nível intermediário de programação. Ele reduz a verbosidade do código, previne erros fatais e melhora a legibilidade. Ao entender como evitar KeyError usando defaultdict no Python, você escreve scripts mais robustos, prontos para lidar com dados ruidosos ou incompletos sem falhar no meio do processo.

Se você deseja explorar outras formas de manipular coleções e otimizar seu tempo de desenvolvimento, conheça também o itertools para iniciantes, que oferece ferramentas complementares para lidar com iterações complexas de maneira elegante.

Perguntas Frequentes

O que acontece se eu não passar nenhum argumento para o defaultdict?

Se você não passar uma fábrica (default_factory), ele se comportará exatamente como um dicionário comum e continuará levantando KeyError para chaves inexistentes.

O defaultdict é mais lento que um dicionário comum?

Não. Na maioria das operações de busca e inserção, a diferença é desprezível. Em loops de inicialização, ele costuma ser até mais rápido que um dict comum com verificações manuais.

Posso usar qualquer função como default_factory?

Sim, desde que a função possa ser chamada sem argumentos. Se você precisar passar parâmetros, deverá usar uma função lambda ou a função partial do módulo functools.

Como verifico se uma chave realmente existe sem criá-la no defaultdict?

Você pode usar o operador in (ex: if 'chave' in meu_dd). O operador in não aciona a criação automática da chave, ao contrário do acesso direto via colchetes.

O defaultdict funciona com JSON?

Você pode converter um defaultdict para JSON usando o módulo json, mas ele será salvo como um objeto-dicionário padrão. Ao carregar de volta, ele será um dict normal.

É possível mudar a fábrica de um defaultdict depois de criado?

Sim, você pode acessar e alterar o atributo default_factory do objeto a qualquer momento durante a execução do programa.

Qual a principal diferença entre defaultdict e dict.setdefault()?

O defaultdict define o comportamento para todo o dicionário na criação, enquanto o setdefault() é um método chamado para chaves específicas durante a execução.

O defaultdict está disponível em todas as versões do Python?

Ele está disponível no módulo collections desde a versão 2.5 do Python, sendo um padrão amplamente suportado na linguagem moderna.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Bibliotecas e Módulos
    Foto do Leandro Hirt

    Como monitorar pastas em tempo real com Python e watchdog

    Monitorar pastas em tempo real com Python e watchdog é uma das formas mais eficientes de criar sistemas automatizados que

    Ler mais

    Tempo de leitura: 9 minutos
    26/03/2026
    Bibliotecas e Módulos
    Foto do Leandro Hirt

    Sem internet? Instale pacotes Python offline em minutos

    Você já se deparou com a situação frustrante de precisar instalar uma biblioteca específica em um servidor isolado ou em

    Ler mais

    Tempo de leitura: 11 minutos
    25/03/2026
    Bibliotecas e Módulos
    Foto do Leandro Hirt

    Compacte arquivos ZIP com Python em 2 minutos

    Aprender como compactar arquivos ZIP com Python é uma das habilidades mais úteis para quem deseja otimizar o armazenamento de

    Ler mais

    Tempo de leitura: 10 minutos
    24/03/2026
    Bibliotecas e Módulos
    Foto do Leandro Hirt

    Copie e mova arquivos em Python com shutil em 2 minutos

    Você já precisou organizar centenas de arquivos em pastas específicas e desistiu por causa do trabalho manual? Se você está

    Ler mais

    Tempo de leitura: 10 minutos
    23/03/2026
    Bibliotecas e Módulos
    Foto do Leandro Hirt

    Como redimensionar imagens com Pillow em Python

    Redimensionar imagens é uma das tarefas mais comuns e fundamentais no processamento de dados visuais. Seja para otimizar o carregamento

    Ler mais

    Tempo de leitura: 10 minutos
    28/02/2026
    FundamentosBibliotecas e Módulos
    Foto do Leandro Hirt

    Descubra como gerar números aleatórios seguros com secrets

    Você já parou para pensar como o seu computador decide qual será o próximo número em um sorteio? No mundo

    Ler mais

    Tempo de leitura: 9 minutos
    27/02/2026