Palavras-chave: Python, listas, cópia, objetos
Em Python as variáveis não armazenam os objetos quando atribuímos um valor à elas. Ao invés disso uma variável em Python guarda apenas uma referência para o objeto em questão. Uma prova disto pode ser vista a seguir:
[python]
>>> a = [1,2,3]
>>> b = a
>>> b is a
True
>>> a.append(4)
>>> b
[1, 2, 3, 4]
[/python]
Por essa razão precisamos fazer cópias dos objetos quando queremos manipular os dados de uma das variáveis sem afetar os dados da outra.
A biblioteca Python disponibiliza o módulo copy para essa tarefa, mas em casos de listas (ou qualquer outra seqüência como strings e tuplas) existe uma maneira mais simples de se fazer isso: utilizando slicing, veja:
>>> a = [1,2,3] >>> b = a[:] >>> a is b False >>> a.append(4) >>> b [1, 2, 3] >>> a [1, 2, 3, 4]
A operação de slicing retornou uma cópia idêntica da lista porque a[:] é o mesmo que a[0:len(a)]. Vale lembrar, porém, que apenas a lista é copiada e não os objetos que estão dentro dela.
Vale lembrar que a necessidade de fazer uma cópia não é tão comum quanto parece.
Outro ponto importante são os objetos imutáveis (como strings e números).
Por exemplo:
a = “Luciano”
b = a
a == b # True
a is b # True
a += ” Pacheco”
a # => “Luciano Pacheco”
b # => “Luciano”
Isso ocorre por que ao fazer “a += ‘ Pacheco'” é criada uma nova string e atribuída à variável “a”. A string inicial que “estava” na variável “a” é ficou intocada e portanto a variável “b” continou com o seu valor.
Luciano,
então nesse caso não utilizado referência como o Osvaldo disse em: “Ao invés disso uma variável em Python guarda apenas uma referência para o objeto em questão”, mas sim feito uma cópia do conteúdo da variavel “a” para o conteúdo de “b”.
Agora confundiu mais ainda :D
Na verdade, o que eu disse está correto e o que o Luciano disse também está correto. São não estamos falando das mesmas coisas :)
Uma coisa é o conceito de mutabilidade de um objeto e outra é como nós referenciamos esse objeto.
Os objetos strings são imutáveis (assim como tuplas, números e mais alguns outros) e quando a gente faz uma concatenação de strings o que ocorre internamente é que uma nova string será criada com o resultado da concatenação e ela será referenciada pela mesma variável.
E o que acontecerá com a string antiga? Ela perde a referência da variável e, caso seja a última referência dela, ela será “coletada” pelo garbage colector. O mesmo ocorre com a string que foi usada para a concatenação.
Ocorre uma abdução coletiva dos codarianos? Saudades das dicas!
Opa, tudo bem?
Me tire essa dúvida se possível!
Se eu tenho a seguinte lista:
>>>> a = [[1,2,3], [4,5,6]]
>>>> b = a[:]
>>>> b[0][0] = 7
>>>> a
>>>> [[7,2,3], [4,5,6]]
>>>> b
>>>> [[7,2,3], [4,5,6]]
Não sei pq ta tratando como referencia, vc sabe o motivo??
E o mais louco, se na minha primeira alteração em b, for da forma:
>>>> b[0] = [7,2,3]
Não tem problema nenhum!
Se alguém estiver com esse problema, use
>>>> import copy
>>>> b = copy.deepcopy(a)
Valeu!
Até mais
Valeu, salvou meu dia :)