Às vezes, você desejará uma cópia completa de um objeto, outras vezes, desejará que ele use referências. Veja as diferenças na ação.

Python oferece várias abordagens eficientes para gerenciamento de dados. Compreender os conceitos de cópia superficial e profunda é crucial ao trabalhar com estruturas de dados como listas aninhadas, dicionários ou objetos personalizados.

Tanto a cópia superficial quanto a profunda permitem fazer réplicas de estruturas de dados, mas elas agem de maneira diferente em relação aos dados aninhados.

Usando cópia superficial

A cópia superficial funciona criando uma cópia da estrutura de nível superior do objeto original. Isso significa que, se o objeto original contiver objetos aninhados, a cópia fará referência aos mesmos objetos aninhados que o original. Em outras palavras, fazer uma cópia superficial de um objeto duplica sua estrutura externa, e não quaisquer objetos aninhados que ele possa conter.

Para realizar uma cópia superficial em Python, você pode usar o módulo copy cópia de() função ou o .cópia de() método no objeto.

instagram viewer

Considere um exemplo de trabalhando com uma lista ou dicionário em Python.

import copy

main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)

# Modify the nested list
shallow_copy[2][0] = 99
main_list[2][1] = 100

print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")

No código acima, o lista_principal variável contém uma lista contendo inteiros e uma lista interna (objeto aninhado) contendo letras. A função copy cria uma cópia do lista_principal que o código armazena em outra variável, cópia superficial.

Quaisquer alterações que você fizer no cópia superficial lista aninhada também afetará diretamente a do lista_principal e vice versa. Essas alterações mostram que a lista aninhada ou interna do cópia superficial é apenas uma referência à do lista_principal, aplicando as alterações em lista_principal também.

Enquanto isso, quaisquer alterações feitas nos itens externos (os inteiros) em qualquer cópia superficial ou lista_principal afetará apenas essa instância. Esses itens externos são valores independentes por direito próprio, e não apenas meras referências.

import copy

main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)

# Modify the outer items
shallow_copy[0] = "M"
main_list[1] = "N"

print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")

A saída demonstra que os itens externos de ambas as listas são independentes um do outro:

A mesma ideia se aplica ao trabalhar com dicionários.

dict1 = {'ten': 10, 'twenty': 20, 'double':{'thirty': 30, 'sixty': 60}}
dict2 = dict1.copy()

# Modify inner and outer elements
dict1['double']['thirty'] = 30.00
dict1['ten'] = 10.00

print(f"The main dictionary, {dict1}")
print(f"The shallow copy dictionary, {dict2}")

Alterações feitas no dicionário aninhado de ditado1 afetar ambos ditado1 e ditado2. Ao mesmo tempo, alterações nos itens externos do ditado1 afeta apenas isso.

Usando cópia profunda

Em vez de fazer referência aos objetos aninhados da cópia original, uma cópia profunda faz uma cópia totalmente separada do objeto original e de seus objetos aninhados. Modificar a cópia profunda não afetará o objeto original e vice-versa; eles são valores verdadeiramente separados.

Para fazer uma cópia profunda em Python, use o cópia profunda() função do módulo de cópia.

Considere um exemplo de trabalho com uma lista.

import copy

main_list = [200, 300, ["I", "J"]]
deep_copy = copy.deepcopy(main_list)

# Modify the inner and outer list
deep_copy[2][0] = "K"
main_list[0] = 500

print(f"The main list: {main_list}")
print(f"The deep copy list: {deep_copy}")

Aqui, o código executa uma cópia profunda de lista_principal, criando uma cópia independente chamada cópia profunda.

Quando você modifica a lista aninhada ou os itens externos no cópia profunda, suas alterações não afetarão a lista original e vice-versa. Isso demonstra que a lista aninhada ou os elementos externos não são compartilhados entre as duas cópias.

Trabalhando com objetos personalizados

Você pode criar um objeto personalizado definindo uma classe Python e criando uma instância da classe.

Aqui está um exemplo de criação de um objeto simples a partir de um Livro aula:

classBook:
def__init__(self, title, authors, price):
self.title = title
self.authors = authors
self.price = price

def__str__(self):
returnf"Book(title='{self.title}', author='{self.authors}', \
price='{self.price}')"

Agora, faça uma cópia superficial e uma cópia profunda de uma instância deste Livro aula usando o cópia de módulo.

import copy

# Create a Book object
book1 = Book("How to MakeUseOf Shallow Copy", \
["Bobby Jack", "Princewill Inyang"], 1000)

# Make a shallow copy
book2 = copy.copy(book1)

# Modify the original object
book1.authors.append("Yuvraj Chandra")
book1.price = 50

# Check the objects
print(book1)
print(book2)

Como você pode ver, a cópia superficial (livro2) é um objeto novo, mas faz referência ao mesmo objeto interno (lista de autores) que o objeto original (livro1). Portanto, uma alteração nos autores do objeto original afeta ambas as instâncias (livro1 e livro2), enquanto uma alteração no item externo (preço) afeta apenas o objeto original (livro1).

Por outro lado, fazer uma cópia profunda cria uma cópia independente do objeto original, incluindo cópias de todos os objetos contidos nele.

# Create a Book object
book1 = Book("Why MakeUseOf Deep Copy?", \
["Bobby Jack", "Yuvraj Chandra"], 5000)

# Make a deep copy
book2 = copy.deepcopy(book1)

# Modify the original object
book1.authors.append("Princewill Inyang")
book1.price = 60

# Check the objects
print(book1)
print(book2)

Neste caso, a cópia profunda (livro2) é um objeto completamente independente e modificando o objeto original (livro1) não o afeta.

Usos para cópia superficial e cópia profunda

É vital compreender a cópia profunda e superficial para que você possa selecionar a abordagem apropriada para a manipulação de dados. Aqui estão alguns cenários em que cada método é aplicável:

  • Use uma cópia superficial se quiser replicar um objeto complexo sem gerar novas instâncias de seus objetos aninhados. Essa abordagem é mais eficiente em termos de memória e mais rápida do que a cópia profunda porque não duplica objetos aninhados.
  • Use uma cópia superficial para criar um instantâneo do estado de um objeto enquanto ainda compartilha alguns dados subjacentes entre os objetos originais e copiados.
  • Use uma cópia profunda se quiser modificar uma réplica de um objeto sem afetar o original. Isso gera cópias independentes de objetos aninhados, garantindo que quaisquer alterações na cópia não se apliquem ao original.
  • A cópia profunda é crítica quando você precisa de cópias independentes de estruturas de dados aninhadas, principalmente ao lidar com hierarquias de objetos recursivas ou complexas.

Desempenho e considerações

Como a cópia superficial não gera novas instâncias de objetos aninhados, ela normalmente é executada mais rapidamente e usa menos memória que a cópia profunda. No entanto, o original e a cópia superficial podem ter efeitos colaterais indesejados devido à alteração de itens internos compartilhados.

Especialmente para estruturas de dados grandes e profundamente aninhadas, cópia profunda, um procedimento recursivo, pode ser mais lento e usar mais memória. No entanto, garante total independência entre o original e a duplicata profunda, tornando a manipulação complexa de dados mais segura.

A melhor opção de cópia para seus dados

Muitas linguagens de programação usam o conceito de cópia superficial e profunda. Entendê-lo permite manipular dados sem consequências imprevistas.

Usando técnicas de cópia superficial e profunda, você pode selecionar a melhor abordagem para duplicar suas estruturas de dados com segurança. Ao compreender os efeitos nos seus dados, você obterá resultados mais confiáveis ​​e previsíveis do seu código.