割り当て後に予期せず変更されないようにリストを複製するにはどうすればよいですか? 質問する

割り当て後に予期せず変更されないようにリストを複製するにはどうすればよいですか? 質問する

を使用している間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_listmy_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)]

おすすめ記事