Jaké jsou možnosti klonování nebo kopírování seznamu v jazyce Python?
Při použití new_list = my_list
se při jakékoli změně new_list
vždy změní my_list
.
Proč tomu tak je?
Při použití new_list = my_list
ve skutečnosti nemáte dva seznamy. Přiřazení pouze kopíruje odkaz na seznam, nikoliv skutečný seznam, takže jak new_list
, tak my_list
odkazují po přiřazení na stejný seznam.
Chcete-li seznam skutečně zkopírovat, máte různé možnosti:
Můžete použít vestavěnou metodu list.copy()
(k dispozici od verze Python 3.3):
Nový_seznam = starý_seznam.kopírovat()
Můžete jej nakrájet na plátky:
new_list = old_list[:]
Alex Martelli's názor (alespoň [v roce 2007][2]) na to je, že je to divná syntaxe a nemá smysl ji nikdy používat. ;) (Podle jeho názoru je další čitelnější).
Můžete použít vestavěnou funkci list()
:
nový_seznam = seznam(starý_seznam)
Můžete použít obecnou funkci copy.copy()
:
import copy
new_list = copy.copy(old_list)
Tento postup je o něco pomalejší než list()
, protože musí nejprve zjistit datový typ old_list
.
Pokud seznam obsahuje objekty a chcete je také zkopírovat, použijte obecný copy.deepcopy()
:
import copy
new_list = copy.deepcopy(old_list)
Zřejmě nejpomalejší a paměťově nejnáročnější metoda, ale někdy se jí nelze vyhnout.
Příklad:
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))
Výsledek:
original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]