2017-01-23 1 views
0

私は、リストを初期化するためにPythonで[Value] * Count表記を使用しています。たとえば、[False] * 3の場合はリスト[False, False False]が作成されます。私はリストのリストを初期化するために同じ表記法を使ってみました。Pythonリスト内の可変オブジェクトのID

>>>a = [[0] * 2] * 3 
>>>print a 
[[0, 0], [0, 0], [0, 0]] 
>>>a[0][1] = 23 
>>>print a 
[[0, 23], [0, 23], [0, 23]] 
>>>id(a[0]) 
139978350226680 
>>>id(a[1]) 
139978350226680 
>>>id(a[2]) 
139978350226680 

わかりましたように、aの要素は、3つの異なるリストを参照する代わりに、3つのリストを参照しています。 1.これはなぜ起こりますか? 2.リストのリストを初期化する正しい方法は何ですか? https://stackoverflow.com/a/13382804/4716199リストに*オペレータの行動だ

+0

"正しい"方法は、forループまたはリストの理解を使用することです。 –

+0

'b = [0] * 2;を実行した場合、 a = [b] * 3 '' a'は 'b'への参照を3つ含んでいるのに驚くでしょうか? –

+0

@ PM2Ringそれは理にかなっています。私は*新しいコピーを作成しないことを知らなかった、単に参照をコピーします。ありがとう:) – Sidhant

答えて

1

:それはコピーことはありませんが、コピー参照

同じ動作

は、以前の回答で指摘されています。それは一般的なので意味があります は定義されていませんコピーを作成する方法は、オブジェクトが持つ唯一のものなので、Pythonは参照をコピーすることができます。場合

は、あなたがリストの内包表記を使用することができ、新しいリストを構築したい。一般的には

a = [[0] * 2 for _ in range(3)] 

リスト与え*を使用するない良い方法で変更可能なオブジェクト含まれています。

boolstrのような不変オブジェクトの場合、はオブジェクトではなく結果の配列上で動作します。あなたの例では、連鎖インデックスを使用したので、内側のリストを変更します。

関連する問題