どんなセカンドライフがいい?

セカンドライフへのウォーミングアップ

2次元配列の初期化について

atCoderコンテストではマス目を使用した問題が良く出題されます。先週のABC339 Bの問題でも出題されたのですが、横5列、縦3行のマス目の配列をドット文字で初期化しようと以下のようにコーディングしました。

L = [["."]*5]*3

for l in L:
    print("".join(l))

#出力結果
.....
.....
.....

出力結果をみると特に問題ないように見えますが、以下のように左上のマス(L[0][0])の値を "*"に変更するようコーディングしたところ、一列すべての値が変更されてしまいました。(°ω°)

L = [["."]*5]*3

L[0][0] = "*"

for l in L:
    print("".join(l))

#出力結果
*....
*....
*....

これは、行を表すリスト(["."]*5)を3行作ってますが、この行リストがすべて同じオブジェクトを指していることが原因です。同じリストの先頭アドレスを持った3行のリストを作っているのでした。

解決策

解決策としては、以下のようにしてforループで回して初期化する必要があります。

L = [["."] * 5 for _ in range(3)]

L[0][0] = "*"

for l in L:
    print("".join(l))

#出力結果
*....
.....
.....