O GIST a ser adotado é o seguinte: Lidar com listas rasas (sem sub-listas, apenas elementos únicos) usando "atribuição normal" aumenta um "efeito colateral" quando você cria uma lista superficial e depois cria uma cópia dessa lista usando "atribuição normal" . Esse "efeito colateral" ocorre quando você altera qualquer elemento da lista de cópias criada, porque altera automaticamente os mesmos elementos da lista original. É quando isso é copy
útil, pois não altera os elementos da lista original ao alterar os elementos de cópia.
Por outro lado, copy
também tem um "efeito colateral", quando você tem uma lista que contém listas (sub_lists) e a deepcopy
resolve. Por exemplo, se você criar uma grande lista que contém listas aninhadas (sub_lists) e criar uma cópia dessa grande lista (a lista original). O "efeito colateral" surgiria quando você modificar as sub-listas da lista de cópias, que modificariam automaticamente as sub-listas da grande lista. Às vezes (em alguns projetos) você deseja manter a grande lista (sua lista original) sem modificações, e tudo o que você deseja é fazer uma cópia de seus elementos (sub_lists). Para isso, sua solução é usar o deepcopy
que cuidará desse "efeito colateral" e fará uma cópia sem modificar o conteúdo original.
Os diferentes comportamentos copy
e deep copy
operações dizem respeito apenas a objetos compostos (ou seja: objetos que contêm outros objetos, como listas).
Aqui estão as diferenças ilustradas neste exemplo de código simples:
Primeiro
vamos verificar como copy
(raso) se comporta, criando uma lista original e uma cópia desta lista:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
Agora, vamos executar alguns print
testes e ver como a lista original se compara à sua lista de cópias:
original_list e copy_list têm endereços diferentes
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
elementos da lista original e lista de cópias têm os mesmos endereços
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
sub_elements de original_list e copy_list têm os mesmos endereços
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x1faef08 0x1faef08
modificar elementos da lista original NÃO modifica os elementos da lista cópia
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
modificar elementos copy_list NÃO modifica elementos original_list
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
modificar sub_elements da lista original modificar automaticamente sub_elementos da cópia
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 7]
modificar sub_elementos copy_list modificar automaticamente sub_elements original_list
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 7]
Segundo
vamos verificar como deepcopy
se comporta, fazendo o mesmo que fizemos com copy
(criando uma lista original e uma cópia desta lista):
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
Agora, vamos executar alguns print
testes e ver como a lista original se compara à sua lista de cópias:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.deepcopy(original_list)
original_list e copy_list têm endereços diferentes
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
elementos da lista original e lista de cópias têm os mesmos endereços
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
sub_elements de original_list e copy_list têm endereços diferentes
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x24eef08 0x24f3300
modificar elementos da lista original NÃO modifica os elementos da lista cópia
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
modificar elementos copy_list NÃO modifica elementos original_list
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
modificar sub_elements da lista original NÃO modifica os sub_elementos da cópia
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
modificar sub_elementos copy_list NÃO modifica sub_elements original_list
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'd'], 7]