例を見てみましょう
a=['help', 'copyright', 'credits', 'license']
b=a
b.append('XYZ')
b
['help', 'copyright', 'credits', 'license', 'XYZ']
a
['help', 'copyright', 'credits', 'license', 'XYZ']
リスト「b」に値を追加したかったのですが、リスト「a」の値も変更されました。
[。
私の質問は、「 'b'を追加しても 'a'の値が変わらないように値で渡すにはどうすればよいですか?」です。
公式Python FAQ で回答されています:
b = a[:]
リストをコピーするには、list(a)
またはa[:]
を使用できます。どちらの場合も、新しいオブジェクトが作成されます。
ただし、これらの2つのメソッドには、内部オブジェクトが参照をそのまま保持するため、可変オブジェクトのコレクションに制限があります。
>>> a = [[1,2],[3],[4]]
>>> b = a[:]
>>> c = list(a)
>>> c[0].append(9)
>>> a
[[1, 2, 9], [3], [4]]
>>> c
[[1, 2, 9], [3], [4]]
>>> b
[[1, 2, 9], [3], [4]]
>>>
オブジェクトの完全なコピーが必要な場合は、 copy.deepcopy が必要です。
>>> from copy import deepcopy
>>> a = [[1,2],[3],[4]]
>>> b = a[:]
>>> c = deepcopy(a)
>>> c[0].append(9)
>>> a
[[1, 2], [3], [4]]
>>> b
[[1, 2], [3], [4]]
>>> c
[[1, 2, 9], [3], [4]]
>>>
パフォーマンスに関して、私のお気に入りの答えは次のとおりです。
b.extend(a)
パフォーマンスの観点から、関連する代替案が互いにどのように比較されるかを確認します。
In [1]: import timeit
In [2]: timeit.timeit('b.extend(a)', setup='b=[];a=range(0,10)', number=100000000)
Out[2]: 9.623248100280762
In [3]: timeit.timeit('b = a[:]', setup='b=[];a=range(0,10)', number=100000000)
Out[3]: 10.84756088256836
In [4]: timeit.timeit('b = list(a)', setup='b=[];a=range(0,10)', number=100000000)
Out[4]: 21.46313500404358
In [5]: timeit.timeit('b = [elem for elem in a]', setup='b=[];a=range(0,10)', number=100000000)
Out[5]: 66.99795293807983
In [6]: timeit.timeit('for elem in a: b.append(elem)', setup='b=[];a=range(0,10)', number=100000000)
Out[6]: 67.9775960445404
In [7]: timeit.timeit('b = deepcopy(a)', setup='from copy import deepcopy; b=[];a=range(0,10)', number=100000000)
Out[7]: 1216.1108016967773
また、次のことができます。
b = list(a)
これは、インデクサーとスライスをサポートしていないシーケンスでも動作します...
一次元のリストをコピーしたい場合は、
b = a[:]
ただし、a
が2次元リストの場合、これは機能しません。つまり、a
の変更は、b
にも反映されます。その場合、使用
b = [[a[x][y] for y in range(len(a[0]))] for x in range(len(a))]
Phihagの答えで述べたように、
b = a[:]
リストをスライスするとリストの新しいメモリIDが作成されるため、あなたのケースで機能します(つまり、メモリ内の同じオブジェクトを参照しなくなり、一方に加えた変更が他方に反映されないことを意味します)。
ただし、わずかな問題があります。リスト内のリストのようにリストが多次元の場合、単にスライスしてもこの問題は解決しません。高次元で行われた変更、つまり元のリスト内のリストは、2つの間で共有されます。
心配しないでください、解決策があります。モジュールコピーには、この問題を処理する巧妙なコピー手法があります。
from copy import deepcopy
b = deepcopy(a)
リストに含まれるリストのレベルに関係なく、新しいメモリIDでリストをコピーします!
b = a
を実行すると、単にaの同じメモリへの別のポインターを作成するため、bに追加するとaも変わります。
copy of aを作成する必要があり、これは次のように行われます。
b = a[:]
リストのコピーを作成するには、次を実行します。
b = a[:]
Extend()を使用してcopy()の機能を実装できることがわかりました
a=['help', 'copyright', 'credits', 'license']
b = []
b.extend(a)
b.append("XYZ")
次の解決策をお勧めします。
b = []
b[:] = a
これにより、すべての要素がaからbにコピーされます。コピーは参照コピーではなく、値のコピーになります。
b = list(a)
http://henry.precheur.org/python/copy_list を参照してください。