Python Dicionários: Método Copy Explicado
Aprenda todas as formas de copiar um dicionário Python — copy(), dict(), {**d} e deepcopy() — com exemplos claros de cópia shallow vs. deep.
Este capítulo explica todas as formas padrão de copiar um dicionário Python, por que uma atribuição simples (=) não é uma cópia e quando você precisa de uma cópia profunda (deep copy) em vez de uma cópia rasa (shallow copy).
Por Que Você Não Pode Copiar um Dicionário com =
Atribuir um dicionário a uma nova variável não cria uma cópia — cria uma segunda referência ao mesmo objeto. Qualquer alteração feita por qualquer uma das variáveis afeta o mesmo dicionário subjacente.
original = {'a': 1, 'b': 2}
alias = original # same object, not a copy
alias['c'] = 3
print(original) # {'a': 1, 'b': 2, 'c': 3} — original changed!Para obter um dicionário verdadeiramente independente, você precisa de um dos métodos de cópia mostrados abaixo.
Cópia Shallow vs. Cópia Deep
Antes de analisar os métodos, é útil entender os dois tipos de cópia:
| Tipo | O que é copiado | Mutáveis aninhados |
|---|---|---|
| Cópia shallow | Pares chave-valor do nível superior | As referências são compartilhadas — a mutação em um dicionário afeta o outro |
| Cópia deep | Cada objeto em cada profundidade | Totalmente independente — sem referências compartilhadas |
Para dicionários simples (cujos valores são strings, números, None, booleanos), uma cópia shallow é sempre suficiente. Para dicionários que contêm listas, conjuntos ou outros dicionários como valores, considere uma cópia deep.
Método 1: dict.copy()
O método built-in copy() retorna um novo dicionário que é uma cópia shallow do original. É a escolha mais idiomática para dicionários simples.
Sintaxe
new_dict = original_dict.copy()Fazer uma cópia shallow de um dicionário em Python
Adicionar ou remover uma chave em new_dict deixa original_dict intacto, pois a cópia do nível superior é independente.
Atualizando chaves do nível superior em um dicionário copiado
Método 2: Construtor dict()
Passar um dicionário existente para o construtor dict() cria uma cópia shallow da mesma forma que copy().
original_dict = {'name': 'Alice', 'age': 30}
new_dict = dict(original_dict)
new_dict['age'] = 31
print(original_dict) # {'name': 'Alice', 'age': 30}
print(new_dict) # {'name': 'Alice', 'age': 31}dict() é útil quando você quer ser explícito ao criar um dicionário a partir de outro mapeamento ou quando combina argumentos nomeados com um dicionário existente:
defaults = {'color': 'blue', 'size': 'M'}
custom = dict(defaults, size='L', weight='light')
print(custom)
# {'color': 'blue', 'size': 'L', 'weight': 'light'}Método 3: Desempacotamento de Dicionário {**d}
O operador de desempacotamento ** mescla um dicionário em um novo literal de dicionário. Para uma cópia simples, ele se comporta de forma idêntica a copy(), mas também permite mesclar vários dicionários ou substituir chaves individuais em uma única expressão.
original_dict = {'a': 1, 'b': 2}
new_dict = {**original_dict}
new_dict['c'] = 3
print(original_dict) # {'a': 1, 'b': 2}
print(new_dict) # {'a': 1, 'b': 2, 'c': 3}Copiando enquanto substitui uma chave
config = {'host': 'localhost', 'port': 5432, 'debug': False}
prod_config = {**config, 'host': 'db.example.com', 'debug': False}
print(prod_config)
# {'host': 'db.example.com', 'port': 5432, 'debug': False}Assim como copy(), esta é uma cópia shallow — os mutáveis aninhados ainda são compartilhados.
Armadilha da Cópia Shallow: Mutáveis Aninhados São Compartilhados
Todos os três métodos acima produzem cópias shallow. Quando um valor é em si um objeto mutável (como uma lista), tanto o original quanto a cópia mantêm uma referência ao mesmo objeto interno.
Atualizando valores mutáveis dentro de um dicionário copiado
Ambos os dicionários refletem a alteração porque new_dict['key1'] e original_dict['key1'] apontam para o mesmo objeto lista. Este é o comportamento esperado de uma cópia shallow — não é um bug.
Método 4: copy.deepcopy() para Independência Total
Quando você precisa de isolamento completo — incluindo listas, conjuntos e dicionários aninhados — use copy.deepcopy() do módulo copy da biblioteca padrão. Ele copia recursivamente cada objeto na estrutura.
Cópia deep em Python
deepcopy() lida com estruturas aninhadas arbitrariamente e até com objetos autorreferenciais. Sua desvantagem é velocidade e memória: é mais lento que uma cópia shallow porque precisa percorrer e duplicar todo o grafo de objetos.
Escolhendo o Método Certo
| Situação | Método recomendado |
|---|---|
| Dicionário simples (sem mutáveis aninhados) | dict.copy() ou {**d} |
| Mesclar / substituir chaves ao copiar | {**d, key: value} ou dict(d, key=value) |
| Mutáveis aninhados, precisa de independência total | copy.deepcopy() |
| Converter outro mapeamento em cópia de dicionário | dict(mapping) |
Resumo
- O operador
=cria um alias, não uma cópia. dict.copy(),dict()e{**d}produzem cópias shallow — as chaves do nível superior são independentes, mas os mutáveis aninhados são compartilhados.copy.deepcopy()produz uma cópia deep — cada objeto em cada profundidade é duplicado.- Para dicionários simples, prefira
dict.copy()pela clareza. - Use
{**d, overrides}quando precisar copiar e modificar em uma única expressão.
Veja também: Métodos de Dicionário · Dicionários Aninhados · Iterar em Dicionários