1
>>> a = [1,2,3]
>>> b = a[:]
>>> id(a[0]) == id(b[0])
True
>>> b[0] = 99
>>> id(a[0]) == id(b[0])
False

浅いコピーを作成するには、スライスを使用できることと、コピー モジュールがあることを理解しています。しかし、なぜ "b" のインデックスに書き込むと ID が変わるのでしょうか。

4

4 に答える 4

5

パート 1: 通話が原因のb[0] = 99原因はa[0] == b[0] >> False?

あなたの質問への答えはb[0] = 99、「Bのフィールドの1つが指すメモリアドレスを変更する」のではなく、実際にBのフィールドの1つが指す場所を変更するということです。

a = [1,2,3]  

aオブジェクトへの参照が含まれるようになりました。これには、3 つのオブジェクトlistへの 3 つの参照が含まれintます。

b = a[:]

現在、b はlistオブジェクト (参照先と同じものではない) を参照し、3 つのオブジェクトaへの 3 つの参照 (参照先と同じもの) を含んでいます。inta

id(a) == id(b)
#False

とは異なるオブジェクトへの参照であるためa、誤りです。blist

id(a[0]) == id(b[0])
#True

確かに、はオブジェクトa[0]への参照であり、 もそうです。オブジェクトは 1 つだけで、 と で参照されます。1b[0]1a[0]b[0]

b[0] = 99  
# ^^^^^^ THIS IS NOT WHAT THE WIKIPEDIA ARTICLE IS DESCRIBING

bは引き続き同じ古いlistオブジェクトを参照しますが、b[0]現在は99オブジェクトを参照しています。参照先の参照の 1 つを別のオブジェクトへの新しい参照にlist置き換えただけです。を指しているオブジェクトは変更されbいません!a

id(a[0]) == id(b[0]) 
#False

1オブジェクトがオブジェクトと同じオブジェクトではないため、False 99


パート 2: では、そのウィキペディアの記事は一体何について話しているのでしょうか?

これは、実際に「B のフィールドの 1 つが指すメモリ アドレスを変更する」コピー操作の例です。これにより、コピーされたオブジェクトのその後の変更を確認できます。

a = [[1],[2],[3]]

aはオブジェクトへの参照ですlistが、現在、listオブジェクトにはオブジェクトへの 3 つの参照がlist含まれており、それぞれにオブジェクトへの参照が含まれていintます。

b = a[:]

以前と同様に、b新しい別のlistオブジェクトを参照しました。このオブジェクトは、 で参照されているのと同じ 3 つのlistオブジェクトを参照していaます。証拠は次のとおりです。

id(a) == id(b)
# False

aと同じように、 とbは異なるlistオブジェクトへの参照であるため、誤りです。

id(a[0]) == id(b[0]) 
#True

前と同じように、 と の両方が同じオブジェクトa[0]を参照するためです。b[0]今回は、オブジェクトとは異なり、不変listではないオブジェクトです。オブジェクト の内容を実際に変更できます。ここが違うところです:intlist

b[0][0] = 99  

やった - が参照するオブジェクトの内容を変更しlistb[0]

a[0][0]
# 99 !!!!!!!!!!!!!!  Wikipedia doesn't need to be edited!

見る?listによって参照される「リスト」aは、99オブジェクトではなくオブジェクトを参照します。これは、 でアクセスし1たものと同じであるためです。シンプルですね ;)listb[0][0] = 99

id(a[0]) == id(b[0])
#True !!!

a[0]確かに、参照先の内容は変更しましたが、参照自体は変更していません。これは、ウィキペディアの記事の「浅いコピー」セクションで説明されている内容に近いものです。a[0]b[0]

于 2013-08-16T03:48:22.117 に答える