Python 多重配列の初期化の罠

普段、Pythonを使っている人には、常識?

少しハマってしまったのでメモ。

二次元配列を初期化したくて以下のようにすると、1つの要素を変更すると全部の要素が書き換わっていました。

>>> vs = [[100,0]]*3
>>> print(vs)
[[100, 0], [100, 0], [100, 0]]

>>> vs[0][0] = 50
>>> print(vs)
[[50, 0], [50, 0], [50, 0]]

リストオブジェクトへの参照の配列になっているようです。

>>> v = [100,0]
>>> vs = [v]*3
>>> vs[0][0] = 50
>>> print(vs)
[[50, 0], [50, 0], [50, 0]]

リスト内包表記で回避できました。

>>> vs = [[100, 0] for _ in range(3)]
>>> print(vs)
[[100, 0], [100, 0], [100, 0]]

>>> vs[0][0] = 50
>>> print(vs)
[[50, 0], [100, 0], [100, 0]]