Opa Luan, tudo bem?
Para ajudar na resposta vou criar uma classe teste que tem um atributo número, tudo bem?
class Teste:
def __init__(self, numero):
self.numero = numero
def __repr__(self):
return str(self.numero)
A partir dela, criamos seis objetos testes:
teste1 = Teste(1)
teste2 = Teste(2)
teste3 = Teste(3)
teste6 = Teste(6)
teste9 = Teste(9)
teste30 = Teste(30)
Quando atribuirmos l1
em l2
, o que ocorre é que as duas variáveis apontam para o mesmo endereço de memória, por isso, o id
das duas é igual:
l1 = [teste1, teste2, teste3, teste6, teste9, teste30]
l2 = l1
print(f'L1 = {l1} L2 = {l2}')
print(id(l1) == id(l2)) # por compartilhar o mesmo endereço de memória, o id é o mesmo
# # Resultado
# L1 = [1, 2, 3, 6, 9, 30] L2 = [1, 2, 3, 6, 9, 30]
# True
Quando utilizamos a cópia rasa, criamos outra lista, ou seja, os ids das listas são diferentes, mas o objetos dentro dessa lista tem o mesmo id
, isto é, apontam para o mesmo endereço de memória dos objetos de l1
. Podemos ver isso quando trocamos o número de um objeto teste, as duas listas tem os valores alterados, mesmo sendo listas diferentes:
# Testando Copia Rasa
teste1 = Teste(1)
teste2 = Teste(2)
teste3 = Teste(3)
teste6 = Teste(6)
teste9 = Teste(9)
teste30 = Teste(30)
l1 = [teste1, teste2, teste3, teste6, teste9, teste30]
l2 = l1[:]
l1[2].numero = 7
print('teste3 é atribuído número 7')
print(f'Cópia rasa L1 = {l1} L2 = {l2}')
print(id(l1) == id(l2))
# # Resultado
# teste3 é atribuído número 7
# Cópia rasa L1 = [1, 2, 7, 6, 9, 30] L2 = [1, 2, 7, 6, 9, 30]
# False
Já na cópia profunda, além de uma lista nova, os objetos nas duas listas são diferentes. Ou seja, quando alteramos o número de um objeto teste, ele não é alterado em l2
:
# Testando Copia Profunda
teste1 = Teste(1)
teste2 = Teste(2)
teste3 = Teste(3)
teste6 = Teste(6)
teste9 = Teste(9)
teste30 = Teste(30)
l1 = [teste1, teste2, teste3, teste6, teste9, teste30]
l2 = deepcopy(l1)
print('teste3 é atribuído número 7')
l1[2].numero = 7
print(f'Cópia produnfa L1 = {l1} L2 = {l2}')
print(id(l1) == id(l2))
# # Resultado
# teste3 é atribuído número 7
# Cópia produnfa L1 = [1, 2, 7, 6, 9, 30] L2 = [1, 2, 3, 6, 9, 30]
# False
No caso, tanto na cópia rasa quanto na cópia profunda, por serem listas diferentes, podemos remover um objeto de uma lista sem afetar a outra. Isso porque é uma lista está deixando de apontar para o objeto, mas a outra lista ainda mantém a referência.