6

私はPythonが大好きですが、リファレンスやディープコピーのものは時々私を驚かせます。

ここでディープコピーが機能しないのはなぜですか。

>>> import copy
>>> a = 2*[2*[0]]
>>> a
[[0, 0], [0, 0]]
>>> b = copy.deepcopy(a)
>>> b[0][0] = 1
>>> b
[[1, 0], [1, 0]]     #should be: [[1, 0], [0, 1]]
>>> 

とにかく後で必要になる回避策として、numpy配列を使用しています。しかし、ディープコピーを使用すれば、意図しない参照を追跡する必要がなくなることを本当に望んでいました。それが機能しないトラップは他にありますか?

4

2 に答える 2

15

同じ配列への2つの参照を持つ配列を作成しているため、機能しません。

別のアプローチは次のとおりです。

[[0]*2 for i in range(2)]

または、より明確に:

[[0 for j in range(2)] for i in range(2)]

これは、反復ごとに新しい配列を作成するために機能します。

それが機能しないトラップは他にありますか?

参照を含む配列がある場合は常に注意する必要があります。たとえば[Foo()] * 2、と同じではありません[Foo() for i in range(2)]。最初のケースでは、1つのオブジェクトのみが作成され、配列にはそのオブジェクトへの2つの参照が含まれます。2番目のケースでは、2つの別々のオブジェクトが作成されます。

于 2011-02-01T17:27:17.930 に答える
7

期待どおりに動作します。

a = 2 * [2 * [0]]

を掛ける[[0,0]]2 *、新しいリストの両方の要素が同じリストを指し[0,0]ます。a[0]データではなく参照がコピーされるため、とa[1]は同じリストです(これは不可能です)。一方の最初の要素を変更すると、もう一方の最初の要素も変更されます。

copy.deepcopyリストを正しくコピーし、一意のオブジェクトを保持します。

于 2011-02-01T17:32:01.347 に答える