Pythonでリストのクローンやコピーを行うオプションは何ですか?
new_list = my_listを使用している間、
new_listに変更を加えると、
my_list` が毎回変更されます。
これはなぜですか?
new_list = my_listでは、実際には2つのリストがあるわけではありません。代入はリストへの参照をコピーするだけで、実際のリストをコピーするわけではないので、
new_listも
my_list`も、代入後は同じリストを参照します。
実際にリストをコピーするには、いろいろな方法があります。
Python 3.3以降に搭載された組み込みのlist.copy()
メソッドを利用することができます。
new_list = old_list.copy()
スライスすることもできます。
new_list = old_list[:] となります。
Alex Martelliの意見では、(少なくとも2007年には) それは奇妙な構文であり、それを使うことは意味がない とのことです。(彼の意見では、次のものがより読みやすいそうです)。
組み込みのlist()`関数を使うことができます。
new_list = list(old_list)
汎用のcopy.copy()
関数を使うこともできます。
import copy
new_list = copy.copy(old_list)
まずold_listのデータ型を調べる必要があるので、list()
よりも少し遅くなります。
リストにオブジェクトが含まれていて、それもコピーしたい場合は、ジェネリックのcopy.deepcopy()
を使ってください。
import copy
new_list = copy.deepcopy(old_list)
明らかに最も遅く、メモリを必要とする方法ですが、やむを得ない場合もあります。
**例:***。
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))
結果です。
original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]