Copiar um Dicionário em Python
- Copiar um Dicionário em Python: Passagem por referência
- Copiar um Dicionário em Python: Passar por Valor
- Cópia rasa do Python Dictionary
Este tutorial discute como se pode copiar um dicionário em Python.
Vamos demonstrar como copiar um dicionário de duas maneiras: passando por valor e passando por referência.
Copiar um Dicionário em Python: Passagem por referência
Em Python, os objectos não são implicitamente copiados. Se tentarmos copiar food
para uma nova variável meal
, os valores de food
serão copiados para meal
, mas também o será a referência de food
.
meal = food
A equiparação directa de um objecto a outro fará com que o novo objecto aponte para o anterior; isto significa que as duas variáveis farão referência ao mesmo objecto único.
Se actualizarmos o valor Fruit
em meal
para Banana
, o valor de Fruit
em food
será também substituído.
meal["Fruit"] = "Banana"
print(food)
print(meal)
Resultado:
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
O mesmo acontece se tentarmos actualizar uma chave no bloco meal
. Substituiremos a chave Fruit
por Circle Fruit
e copiaremos o seu valor antes de o retirarmos do dicionário.
meal["Circle Fruit"] = meal.pop("Fruit")
print(food)
print(meal)
Resultado:
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
O valor de food
ainda será substituído mesmo que não o tenhamos modificado directamente; isto porque o método que utilizámos para copiar food
para meal
passa por referência.
Copiar um Dicionário em Python: Passar por Valor
Passar por valor significa que uma cópia real do objecto será criada na memória, em vez de apontar a cópia para o objecto original ao copiar um objecto.
Se quisermos copiar um dicionário e evitar a referência aos valores originais, então devemos encontrar uma forma de instanciar um novo objecto na memória. Em Python, existem algumas funções que apoiam esta abordagem: dict()
, copy()
, e deepcopy()
.
A função dict()
instantia um novo objecto de dicionário. Se envolver um dicionário existente em torno desta função, será criada uma nova instância do objecto.
Para este método, vamos utilizar o mesmo exemplo do dicionário food
.
meal = dict(food)
Outra forma de passar por valor é utilizando o comando copy()
, que faz a mesma coisa que dict()
faz: instanciar um novo objecto na memória. A diferença é que copy()
é uma função integrada de objectos de colecção, incluindo dicionários.
meal = food.copy()
Para ambos os cenários, vamos modificar o valor Fruit
e substituir a chave Vegetable
:
meal["Fruit"] = "Apple"
meal["Greens"] = meal.pop("Vegetable")
print(food)
print(meal)
Resultado:
{'Fruit': 'Orange', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'} # food (original)
{'Fruit': 'Apple', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Greens': 'Lettuce'} # meal (copy)
Ao instanciar um novo objecto meal
utilizando dict()
ou copy()
, evitamos a referência ao objecto original e a actualização dos seus valores se a meal
for actualizada.
Cópia rasa do Python Dictionary
O problema com dict()
e copy()
é que eles só aplicam uma cópia superficial ao objecto a ser utilizado; isto será um problema se o seu dicionário tiver uma estrutura aninhada complexa.
A cópia rasa apenas copiará a primeira camada na memória que vê porque os objectos aninhados ocupam novos espaços.
Vamos mudar o objecto original para um dicionário aninhado.
info = {
"Numbers": [1, 2, 3],
"Resident Name": "Sherlock",
"Address": {"Street": "Baker", "Number": "221B", "City": "Miami"},
}
Vamos declarar um novo objecto info2
utilizando copy()
e dict()
para copiar de info
e alterar alguns valores no dicionário aninhado.
info2 = info.copy() # or dict(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Resultado:
{'Numbers': [1, 4, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
Os novos valores de Numbers
e Address.City
são actualizados tanto na versão original como na versão de cópia. O valor Resident Name
apenas actualizou o bloco info2
porque só executámos uma cópia rasa no objecto.
Cópia profunda com o módulo copy
em Python
A cópia profunda resolve essencialmente o problema da cópia superficial. Ao copiar um objecto, verifica a existência de objectos aninhados e cria recursivamente novos objectos na memória.
Em Python, podemos conseguir uma cópia profunda com o módulo copy
, que contém operações e utilidades de cópia rasa e profunda.
import copy
Utilizaremos a função deepcopy()
do módulo para copiar em profundidade os objectos aninhados dentro do nosso dicionário. Utilizaremos o mesmo exemplo do bloco info
acima.
info2 = copy.deepcopy(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Resultado:
{'Numbers': [1, 2, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Miami'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
Agora, o dicionário original info
permanece inalterado, mesmo com as múltiplas alterações no info2
, incluindo os objectos aninhados.
Em resumo, há muitas maneiras de copiar um dicionário em Python, mas a saída não será a mesma para todos. A atribuição directa de um dicionário com =
passa-o por referência, apontando para o objecto original.
Funções de cópia rasa como dict()
e copy()
resolverão esse problema apenas para dicionários não aninhados.
A melhor maneira de copiar um dicionário, considerando dicionários aninhados, é utilizar a função deepcopy()
fornecida pelo módulo copy
.
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn