Utilizando o Método deepcopy em Python

Como realizar uma cópia profunda e construir objetos recursivamente com o deepcopy.

Introdução

Ainda continuando os nossos estudos sobre referências e métodos built-ins em Python, iremos exemplificar um caso de estudo do método deepcopy(), encontrado no módulo copy.

No post passado, exploramos o método copy(), o qual realiza uma cópia superficial (shallow copy), ou seja, as instruções passadas apenas criam ligações entre um destino e um objeto. Para coleções que são mutáveis ou contêm itens mutáveis, às vezes é necessária uma cópia para que uma lista copiada de outra possa ser alterada, sem alterar a primeira, sendo necessária uma deep copy. Vejamos no exemplo abaixo:

>>> # Exemplo 1: uma lista a partir de outra com o método copy()
>>> import copy
>>> first_list = ['a', 'b', [1, 2, 3, 4], 'c', ['t', 'e']]
>>> id(first_list)
4434654024
>>> # criando um segunda lista
>>> second_list = copy.copy(first_list) # shallow copy
>>> second_list
['a', 'b', [1, 2, 3, 4], 'c', ['t', 'e']]
>>>id(second_list)
4436657800
>>> second_list is first_list
False

Até agora tudo bem. Desta forma, poderemos remover ou inserir objetos em 'secondlist', sem alterar 'firstlist'...e a resposta é: Depende! Vejamos:

>>> # Exemplo 2: removendo um simples objeto da lista
>>> # iremos remover o valor "b" que está no índice 1
>>> del second_list[1]
>>> second_list
['a', [1, 2, 3, 4], 'c', ['t', 'e']] # beleza!
>>> first_list
['a', 'b', [1, 2, 3, 4], 'c', ['t', 'e']] # show!
>>> second_list == first_list
False
>>> # segundo teste
>>> # remover um item da lista dentro de 'second_list'
>>> del second_list[1][-1] # removemos o valor 4
>>> second_list
['a', [1, 2, 3], 'c', ['t', 'e']] # maravilha!
>>> # first_list permanece inalterado?
>>>first_list
['a', 'b', [1, 2, 3], 'c', ['t', 'e']] # wtf!

Agora lascou, fiquei cabreira. Cadê o 4 que tava aqui! Pois é, a cópia rasa ainda permite que o objeto inicial seja alterado por meio da sua cópia.

Terceiro exemplo, realizando uma cópia utilizando o método deepcopy()

Agora, utilizaremos o método deepcopy() que segundo a documentação:

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

>>> # Exemplo 3: uma cópia profunda com deepcopy()
>>> import copy   # importamos o módulo copy
>>> first_list = ['a', 'b', [1, 2, 3, 4], 'c', ['t', 'e']]
>>> second_list = copy.deepcopy(first_list)
>>> # removeremos o mesmo valor 4
>>> del second_list[2][-1]
>>> second_list
['a', 'b', [1, 2, 3], 'c', ['t', 'e']]
>>> first_list
['a', 'b', [1, 2, 3, 4], 'c', ['t', 'e']]
>>> # Done!

Conclusão

Percebemos claramente o papel que realiza uma shallow copy e uma deep copy, com a diferença de que o segundo “copia” funções e classes (rasas e profundas), retornando o objeto original inalterado.

Ainda há muito a ser explorado em listas. Nos próximos posts, continuaremos os nossos estudos, aprendendo o papel de outros métodos utilizados em listas 💚.

'Simple is better than complex.'

Comments