问题中的代码是嵌套列表理解。以 Python 为例
[x*x for x in range(10)]
返回
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
该语法意味着“收集x*x
其中x
包含的每个元素的值range(10)
”
你当然也可以写类似的东西
[42 for x in range(10)]
那会给
[42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
(这个和上面一模一样,只是x
你要采集的表达式中没有用到值)
然而,“列表理解”本身就是一个表达式,因此它可以用于另一个外部列表理解......例如
[[x*y for x in range(3)] for y in range(4)]
将返回
[[0, 0, 0],
[0, 1, 2],
[0, 2, 4],
[0, 3, 6]]
在数字常量(或任何其他不可变)的特殊情况下,您可以使用更简单的形式来构建矩阵:
[[0] * 3 for x in range(4)]
返回
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
因为将列表乘以整数n
,您会得到一个列表,该列表由n
连接的原始列表的副本组成(因此[0]*5
返回[0, 0, 0, 0, 0]
)。
请注意,但是显然相似
[[0] * 3] * 4
不做同样的事情。原因是虽然仍然显示为
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
在这种情况下,外部列表将由对同一行的 4 个引用组成,而不是 4 个独立的行。这意味着在代码之后
x = [[0] * 3] * 4
x[0][0] = 9
x
包含
[[9, 0, 0],
[9, 0, 0],
[9, 0, 0],
[9, 0, 0]]
并不是
[[9, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
就像由独立行组成的真实矩阵一样。