今回は、多次元配列で*演算には注意しないと、バグが起こるよってことを話します。1年Pythonを描き続けましたが知らなかったので、これは共有させていただきますね。Pythonは、ポインタだの参照だのを意識しなくても良い言語だと思うんですが、これは知っておくべきです。
実験方法
各配列がどの参照をしているかを注目してみましょう。今回の実験は、以下の流れをとります。
- 2次元配列を定義 <- 様々な方法をとります
- 中の配列の0番目append(0)をする
- 実験結果の確認
それでは早速実験です。対話モードにて行います。
シンプルに定義
>>> l = [[], [], []]
>>> l[0].append(0)
>>> l
[[0], [], []]
これはおそらく考えていた通りですね。問題なし。
+演算で定義
>>> l = [[]] + [[]] + [[]]
>>> l[0].append(0)
>>> l
[[0], [], []]
これも想定した通り。問題なし。
*演算で定義
>>> l = [[]] * 3
>>> l[0].append(0)
>>> l
[[0], [0], [0]]
......ん????
全ての要素配列に0が足してありますね...これは知らんかったやつ...
*演算に注意!!!
*演算で配列を定義する際には注意しましょう。
シンプルに定義した場合や+によって定義した配列は、それぞれの配列は別のものとして定義されています。
しかし、*によって定義されたものは、演算対象となった配列の参照そのものさえもコピーされて作られてしまいます。
まとまった挙動を示して欲しいのであれば問題ないですが、大きなくくりの配列にある要素配列に対しては別々に動いて欲しい場合はかなり注意が必要です。
このことを知っておくだけでもバグが出た時に冷静に対処できると思うので、ぜひ覚えておきましょう。