Atribuição como Cópia
Em Python, a atribuição simples de objetos mutáveis, como listas, não cria uma nova cópia, mas sim uma referência ao mesmo objeto na memória. Por exemplo, se definirmos uma lista lista_a e atribuirmos lista_b = lista_a, ambas as variáveis apontam para o mesmo conteúdo. Consequentemente, alterações em lista_a serão refletidas em lista_b, independentemente de os elementos serem mutáveis ou não.
# Atribuição (referência)
lista_original = [1, 2, 3]
lista_referencia = lista_original
lista_original.append(4)
print(lista_original) # Saída: [1, 2, 3, 4]
print(lista_referencia) # Saída: [1, 2, 3, 4]
Cópia Rasa
Para realizar uma cópia rasa, utiliza-se o módulo copy do Python, especificamente a função copy.copy(). Neste caso, uma nova lista é criada com uma nova referência, mas os elementos internos ainda compartilham as mesmas referências de memória. Isso significa que, se os elementos da lista original forem mutáveis, como sublistas, modificações nesses elementos serão visíveis na cópia rasa. Porém, alterações em elementos imutáveis não afetarão a cópia.
import copy
nomes = ['alice', 'bob', 'carol', ['dave', 'eve']]
copia_rasa = copy.copy(nomes)
nomes.append('frank')
print(nomes) # Saída: ['alice', 'bob', 'carol', ['dave', 'eve'], 'frank']
print(copia_rasa) # Saída: ['alice', 'bob', 'carol', ['dave', 'eve']]
nomes[-1].append('grace')
print(nomes) # Saída: ['alice', 'bob', 'carol', ['dave', 'eve', 'grace'], 'frank']
print(copia_rasa) # Saída: ['alice', 'bob', 'carol', ['dave', 'eve', 'grace']]
Cópia Profunda
Uma cópia profunda é obtida com a função copy.deepcopy(), também do módulo copy. Este método cria uma cópia completamente independente, recorrendo recursivamente a todos os elementos. Assim, quaisquer alterações na lista original, mesmo em elementos mutáveis, não impactarão a cópia profunda.
import copy
valores = [100, 200, 300, [400, 500]]
print('ID valores:', id(valores))
print('ID valores[3]:', id(valores[3]))
copia_profunda = copy.deepcopy(valores)
print('ID copia_profunda:', id(copia_profunda))
print('ID copia_profunda[3]:', id(copia_profunda[3]))
valores[3].append(600)
print(valores) # Saída: [100, 200, 300, [400, 500, 600]]
print(copia_profunda) # Saída: [100, 200, 300, [400, 500]]
As operações de cópia rasa e profunda são relveantes principalmente para objetos mutáveis, como listas e dicionários. A atribuição simples mantém a mesma referência, enquanto copy.copy() e copy.deepcopy() oferecem níveis diferentes de independência.