5

私はちょうどPythonの本当に奇妙な何かに会いました:

>>> out=[[0]*3]*3
>>> out
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> out[0][1]
0
>>> out[0][1]=9
>>> out
[[0, 9, 0], [0, 9, 0], [0, 9, 0]]

まあ、明らかに、私が欲しいのは:

[[0, 9, 0], [0, 0, 0], [0, 0, 0]]

変じゃない?私はPythonにあまり詳しくありませんが、Pythonは常にその直感的な動作に感銘を受けます。しかし、それはどのようにこれを思い付くのでしょうか?
...そしてどうすれば必要なものを手に入れることができますか?

ありがとう!

ワット

4

2 に答える 2

9

確かに奇妙な振る舞いですが、それは*オペレーターが浅いコピーを作成するためです。あなたの場合、[0, 0, 0]リストの浅いコピーです。このid()関数を使用して、これらの内部リストが実際に同じであることを確認できます。

out=[[0]*3]*3
id(out[0])
>>> 140503648365240
id(out[1])
>>> 140503648365240
id(out[2])
>>> 140503648365240

内包表記を使用して、次のようにさまざまなリストを作成できます。

out = [ [0]*3 for _ in range(3) ]
于 2012-06-07T23:07:35.063 に答える
8

リスト内の要素を複製するために使用*するのは浅いコピー操作であるため、可変オブジェクトを含むリストでこれを使用すると、同じ可変オブジェクトへの複数の参照が発生します。

代わりに、以下を使用してネストされたリストを初期化します。

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

メソッドを使用すると、の各エントリoutが実際には同じリストへの参照であることがわかります。そのため、次の動作が表示されます。

>>> out = [[0]*3]*3
>>> out[0] is out[1] is out[2]
True
于 2012-06-07T23:05:11.053 に答える