を使用している間new_list = my_list
、 への変更は毎回new_list
変更されます。これはなぜですか。また、これを防ぐには、リストを複製またはコピーするにはどうすればよいですか。例:my_list
>>> my_list = [1, 2, 3]
>>> new_list = my_list
>>> new_list.append(4)
>>> my_list
[1, 2, 3, 4]
ベストアンサー1
new_list = my_list
実際には 2 番目のリストは作成されません。代入では、実際のリストではなく、リストへの参照がコピーされるだけなので、代入後は と の両方new_list
がmy_list
同じリストを参照します。
実際にリストをコピーするには、いくつかのオプションがあります。
内蔵の
list.copy()
メソッド (Python 3.3 以降で利用可能):new_list = old_list.copy()
スライスすることができます:
new_list = old_list[:]
アレックス・マルテッリの意見(少なくとも2007年に) これについての私の意見は、これは奇妙な構文であり、決して使用しても意味がないということです。 ;) (彼の意見では、次のものの方が読みやすいです)。
内蔵の
list()
コンストラクタ:new_list = list(old_list)
ジェネリックを使用できる
copy.copy()
:import copy new_list = copy.copy(old_list)
list()
これは、最初にのデータ型を調べる必要があるため、よりも少し遅くなりますold_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 f'Foo({self.val!r})'
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(f'original: {a}\nlist.copy(): {b}\nslice: {c}\nlist(): {d}\ncopy: {e}\ndeepcopy: {f}')
結果:
original: ['foo', Foo(5), 'baz']
list.copy(): ['foo', Foo(5)]
slice: ['foo', Foo(5)]
list(): ['foo', Foo(5)]
copy: ['foo', Foo(5)]
deepcopy: ['foo', Foo(1)]