我在阅读How to think like a computer scientist这是“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]
不是其他行元素的别名。
aha,难道这不像一个大小为1的特殊行为类型。 我听说“Pythonista”不喜欢特殊情况(正如Python中的Zen所解释的那样)...特殊情况下aren没有足够的特殊性来打破规则......“)。 – fizzbuzz 2009-06-10 11:23:48
误导。 python中没有“原始”这样的东西。一切都是一个对象,并且始终通过引用传递,包括INTEGERS。事实上,变量只是名称引用。这里的问题是列表是可变的,而整数不是。 – nosklo 2009-06-10 11:32:03