Python プログラミング

🔥Pythonで安全に二次元配列を初期化する方法|初心者がハマる参照の罠とは?

Pythonで二次元配列(多次元リスト)を初期化するとき、[[0]*W]*H を使っていませんか?
それ、バグの温床です! 本記事では、正しい初期化方法とその理由を、コード例つきでわかりやすく解説します。


✅ 結論:Pythonでの二次元配列の安全な初期化方法

dp = [[0] * W for _ in range(H)]

この形がベストです。なぜこれが正しくて、他の方法が危険なのか? 以下で詳しく解説します。


❌ 初心者がやりがちな間違い:[[0]*W]*H の落とし穴

🔍 サンプルコード

W = 3
H = 2
dp = [[0]*W]*H
dp[0][0] = 1
print(dp)

🧨 出力結果

[[1, 0, 0], [1, 0, 0]]

なんと、1行目だけ書き換えたはずが、2行目まで変わってしまいました。


🧠 原因:リストの「参照コピー」が発生している

Pythonの [[0]*W]*H は、同じリストオブジェクトをH個コピーしているだけ
つまり、すべての行が同じメモリ(参照)を指しているので、1行を変更すると他の行にも影響します。


✅ 正しい初期化:for文で独立したリストを生成する

dp = [[0] * W for _ in range(H)]

✔ サンプルコード

W = 3
H = 2
dp = [[0]*W for _ in range(H)]
dp[0][0] = 1
print(dp)

🎯 出力結果

[[1, 0, 0], [0, 0, 0]]

期待通り、1行目だけが更新されました。


🛠 実践サンプル:動的計画法(DP)テーブルの初期化

二次元配列の初期化は、動的計画法(DP)などのアルゴリズム実装でもよく使います。

W, H = 5, 5
dp = [[0]*W for _ in range(H)]

# スタートから右下に向かうパスの数(右・下のみ移動)
for i in range(H):
    for j in range(W):
        if i == 0 and j == 0:
            dp[i][j] = 1
        else:
            if i > 0:
                dp[i][j] += dp[i-1][j]
            if j > 0:
                dp[i][j] += dp[i][j-1]

for row in dp:
    print(row)

📝 まとめ:Pythonの二次元配列は「参照」に注意!

書き方安全性説明
[[0]*W]*H❌ 危険同じリストを参照してしまう
[[0]*W for _ in range(H)]✅ 安全毎回新しいリストを生成する

-Python, プログラミング

Copyright© donguri.pyのblog , 2025 All Rights Reserved.