「Python プログラミング」の入門書であるHow to think like a computer scientistを読んでいます。
*
リストに適用されたときの乗算演算子 ( ) の動作を明確にしたいと思います。
関数make_matrixを考えてみましょう
def make_matrix(rows, columns):
"""
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
return [[0] * columns] * rows
実際の出力は
[[0, 7], [0, 7], [0, 7], [0, 7]]
make_matrixの正しいバージョンは次のとおり です。
def make_matrix(rows, columns):
"""
>>> make_matrix(3, 5)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
matrix = []
for row in range(rows):
matrix += [[0] * columns]
return matrix
make_matrixの最初のバージョンが失敗する理由(本の 9.8 で説明されているように) は、
...各行は他の行のエイリアスです...
なぜだろう
[[0] * columns] * rows
原因...各行は他の行のエイリアスです...
だがしかし
[[0] * columns]
つまり、行のそれぞれ[0]
が他の行要素のエイリアスではない理由です。