Quais são as opções para clonar ou copiar uma lista em Python?
Enquanto utiliza new_list = my_list
, qualquer modificação em new_list
muda my_list
todas as vezes.
Porque é que isto acontece?
Com new_list = my_list
, você na verdade não tem duas listas. A atribuição apenas copia a referência para a lista, não a lista real, então ambas new_list' e
my_list' referem-se à mesma lista após a atribuição.
Para realmente copiar a lista, você tem várias possibilidades:
Você pode utilizar o método builtin list.copy()
(disponível desde Python 3.3):
new_list = old_list.copy()
Podes cortá-la:
nova_lista = antiga_lista[:]
A opinião de Alex Martelli (pelo menos [em 2007][2]) sobre isto é, que é uma sintaxe estranha e não faz sentido usá-la nunca. ;) (Na opinião dele, a próxima é mais legível).
Você pode utilizar a função embutida list()
:
new_list = lista(old_list)
Você pode utilizar genérico copy.copy()
:
cópia importada
new_list = copy.copy(old_list)
Isto é um pouco mais lento do que list()
porque tem de descobrir primeiro o tipo de dados da old_list
.
Se a lista contém objetos e você deseja copiá-los também, utilize o genérico copy.deepcopy()
:
cópia importada
new_list = copy.deepcopy(old_list)
Obviamente o método mais lento e mais necessário para a memorização, mas por vezes inevitável.
Exemplo:
import copy
class Foo(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return str(self.val)
foo = Foo(1)
a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)
# edit orignal list and instance
a.append('baz')
foo.val = 5
print('original: %r\n list.copy(): %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r'
% (a, b, c, d, e, f))
Resultado:
original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]