Python3で多次元リストを作成するときにハマったこと


はじめに

今回は、Pythonでプログラムを書いていた際にハマったことについて備忘録的にメモしておきます。
同じようなポイントにハマった方も少なからずいらっしゃるとおもうので、ご参考ください。

今回やりたかったこと

動的計画法を用いたアルゴリズムを実装する際に、多次元リストを作成する必要がありました。

以下のような感じです。

[[[], [], [],[]], 
[[],[],[],[]],
[[],[],[],[]],
[[],[],[],[]],]

要は、リストの要素をリストにしたい。

ハマったポイント

初めに、いつも使うような内包表記で記述しました。

w, h = 3, 4
list_l = [[[]] * w for i in range(h)]
print(list_l) #check

>>>[[[], [], []], [[], [], []], [[], [], []], [[], [], []]]

ここからが問題です。

w, h = 3, 4
list_l = [[[]] * w for i in range(h)]
#print(list_l)

for i in range(w):
    list_l[0][i].append(i)
print(list_l)

>>> [[[0, 1, 2], [0, 1, 2], [0, 1, 2]], [[], [], []], [[], [], []], [[], [], []]]

for文で1つ目のリストに対して、1つずつ.appendを実行すると、すべてのリストが一括で更新されてしまいます。

問題点

問題は以下の部分です。

[[]] * w

これは、複数のリストを宣言するのではなく、複製していることになっています。なので、そのどれかに要素を追加しようとすると、ほかのリストも同様の操作をされてしまいます。

解決策

w, h = 3, 4
list_l =[[[] for i in range(w)] for j in range(h)]
#print(list_l)

for i in range(w):
    list_l[0][i].append(i)
print(list_l)

>>>[[[0], [1], [2]], [[], [], []], [[], [], []], [[], [], []]]