pythonで二次元配列を初期化するときの注意
はじめに
最近pythonで競技プログラミングをやっていて、2次元配列の挙動で注意しておかないといけないことを見つけたのでメモ。
環境
説明
>>>
はインタラクティブモードのアレです
1次元配列
pythonでは以下のように配列を初期化できる
>>> d = [0] * 3 >>> d [0, 0, 0]
要素の変更も容易にできる
>>> d[0] = 1 >>> d [1, 0, 0]
2次元配列
しかし、二次元配列となると話が変わってくる
内側の配列の要素を一つだけ変えようとすると他の配列の要素も変わってしまう
>>> l = [[0]*2]*3 >>> l [[0, 0], [0, 0], [0, 0]] >>> l[0][1] = 1 >>> l [[0, 1], [0, 1], [0, 1]]
id関数でオブジェクトのIDを見てみると、内側の配列のIDが同じことが分かる。
つまり、内側の配列のオブジェクトは全て同じ場所を参照しているので、どれかを変更すると他の配列も変更されてしまう。
>>> id(l[0]) 4319671496 >>> id(l[1]) 4319671496
対策
これを防ぐには、内包表記で初期化するのが良いだろう
>>> l = [[0]*2 for _ in range(3)] >>> l [[0, 0], [0, 0], [0, 0]] >>> l[0][0] = 1 >>> l [[1, 0], [0, 0], [0, 0]]
内側の配列のIDが違うことも確認できる
>>> id(l[0]) 4320008648 >>> id(l[1]) 4320008392
終わりに
pythonで二次元配列を初期化するときは気をつけよう。