2013-06-13 6 views
9
私はPythonのリストがどのように機能するかを理解していたと思っ

... コピーPythonのリスト

>>> a = [1,2,3] 
>>> b = a[:] 
>>> b 
[1,2,3] 
>>> b[1]=100 
>>> b 
[1,100,3] 
>>> a 
[1,2,3] 

これまでのところ、とても良いです。私はaの内容でbを初期化しているので、bは別のオブジェクトを指しています。結果として、bの変化はaに影響しない。

は今、この他の例を見てみましょう:

>>> a = [[1,2,3],[4,5,6],[7,8,9]] 
>>> b = a[:][:] 
>>> b 
[[1,2,3],[4,5,6],[7,8,9]] 
>>> b[1][1] = 100 
>>> b 
[[1,2,3],[4,100,6],[7,8,9]] 
>>> a 
[[1,2,3],[4,100,6],[7,8,9]] 

はなぜBの変化は、この時間に影響を与えていますか?前の例とは何が違うのですか?

+1

コピーするには '[:]'を使うのはややわかりにくいことに注意してください - 一般的に文脈によって 'list()'や 'copy.copy()'を使う方がはるかにいいです。 (もちろん、回答で指摘されているように、 'copy.deepcopy()'があなたの望むものかもしれません)。 –

答えて

11

スライシング操作x[:]は、シャローコピーとなります。つまり、外側のリストは異なりますが、まったく同じ要素が含まれています。 a = [[1]]を前提としています

b = a[:] # is the same as: 
b = [x for x in a] 

>>> a[0] is b[0] 
True 

ダブルスライス([:][:])はそれ以上何もしていない - 再び:

b = a[:][:] # is the same as: 
b = [y for y in [x for x in a]] 

>>> a[0] is b[0] 
True 

浅いコピーの浅いコピーは、よく、浅いコピーです。

したがってbはまだaの浅いコピーです。これらのリストは異なるオブジェクトですが、同じ要素を含んでいます。次に、内部リストをbに変更しますが、それはaの同じリストです。

b=[x[:] for x in a]で2レベルのシャローコピーを行うことができます。これは、nレベルコピーの場合と同じ方法で拡張されます。

ところで、「シャローコピー」という用語は、どのクラスまたはコンテナに対しても同じ意味を持ちます。

実際のディープコピーが必要な場合は、deep copyの使用を検討する必要があります。

+1

「浅いコピー」!私はそのコンセプトを知らなかった。おそらくあなたはそれをもう少し説明するために答えを少し編集することができます。 –

+0

解決策とともに良い説明のために+1 – Sid

+0

@MarcosGonzalezは今より良いですか? – Elazar

4

サイレント[:]はシャローコピーを作成します。 )()との両方のリストにあなたはこの

使用のリスト内包

b = [i[:] for i in a] 

またはcopy.deepcopyが表示されます。しかし、彼らは変更可能であるかのように、内側のオブジェクトがコピーされないままとあなたは、彼らが変更されますそれらを修正します

import copy 
b = copy.deepcopy(a) 
+0

ヒントありがとう! –

1

これを試してみてください:

In [38]: import copy 

In [39]: a = [[1,2,3],[4,5,6],[7,8,9]] 

In [40]: b=copy.deepcopy(a) 

In [41]: b[1][1] = 100 

In [42]: a 
Out[42]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

In [43]: b 
Out[43]: [[1, 2, 3], [4, 100, 6], [7, 8, 9]] 

http://docs.python.org/2/library/copy.htmlを@続きを読みます

+0

ヒントありがとうございます。 –

関連する問題