我正在阅读《像计算机科学家一样思考》这本书,它是一本介绍“Python编程”的入门教材。
我想澄清当应用于列表时乘法运算符(*
)的行为。
考虑函数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]
不是其他行元素的别名。
outerList = [[0]*10 for _ in range(5)]
是Pythonic的,紧凑的,并且不会生成浅拷贝。 - smci