3

私はpythonで浅いコピーで遊んでいます。予想もしていなかった落とし穴に出くわしました。

私の仮定では、浅いコピーは、クラス内のオブジェクトへの参照を持つクラスの新しいインスタンスであるというものでした。この動作を以下に示します。

>>> a = { 'a': 1, 'b':2, 'c': [[1,2],2,3,4,5,6] }
>>> c = copy.copy(a['c'])
>>> d = a['c']
>>> a['c'] is c
False
>>> a['c'][0] is c[0]
True
>>> a['c'] is d
True
>>> a['c'][0] is d[0]
True

驚いたのは以下。浅いコピーされたリストの要素はリスト内の要素への参照であるため、a変更可能な最初の要素を変更すると、a.

>>> c[0] = [3,3]
>>> c
[[3, 3], 2, 3, 4, 5, 6]
>>> a
{'a': 1, 'c': [[1, 2], 2, 3, 4, 5, 6], 'b': 2}
>>> a['c'][0] is c[0]
False

変更後、最初の要素が の参照ではなくなったことがわかりましたa

私の質問:

リスト内のすべての要素を変更すると、ディープコピーに似たものになりますか?

4

1 に答える 1

4

浅いコピーされたリストの要素は「a」からのリスト内の要素への参照であるため、可変の最初の要素を変更すると「a」でも変更されると想定しました。

の最初の要素cは変更可能なリストです。したがって、実際に変異させた場合、結果は に表示されますa。例えば:

>>> a = { 'a': 1, 'b':2, 'c': [[1],2,3,4,5,6] }
>>> c = copy.copy(a['c'])
>>> c[0].append(0)
>>> a
{'a': 1, 'b':2, 'c': [[1, 0], 2, 3, 4, 5, 6]}

しかし、あなたはそれを変異させませんでした。別の値に置き換えただけです。

[1, 2]元の値 ( ) と新しい値 ( ) の両方[3, 3]が可変であるという事実は関係ありません。cあなたは何も変更していません(もちろん、を除いて…しかし、すでに知っているように、同じオブジェクトではなく、cの浅いコピーです)。a['c']

そう:

リスト内のすべての要素を変更すると、ディープコピーに似たものになりますか?

いいえ、2 つの点で。共有要素を変更すると、すべての参照が変更されます。リストのすべての要素を置き換えることは、「ディープコピーに似ています」...しかし、オリジナルのようなコピーで置き換えない限り、同じではありません。deepcopyそれらを浅いコピーに置き換えると、まったく同じ問題を 1 レベル下げるだけになります。例えば:

>>> a = [[[0]]]
>>> b = copy.copy(a[0])
>>> b[0] = copy.copy(b[0])
>>> a[0] is b
False
>>> a[0][0] is b[0]
False
>>> a[0][0][0] is b[0][0]
True

(あなたの例では、それらをまったく異なる無関係な値に置き換えていますが、これはまったくコピーのようなものではありません…しかし、私はあなたが何を意味しているのか知っていると思います。)

于 2013-05-01T17:57:33.993 に答える