优雅地在Python中初始化n维矩阵

1 投票
4 回答
5094 浏览
提问于 2025-04-29 07:10

在StackOverflow上,有几个问题是关于如何初始化一个二维矩阵的,答案通常是这样的:

matrix = [[0 for x in range(10)] for x in range(10)]

有没有什么方法可以把这个过程推广到n维,而不需要使用for循环或者写出非常长的嵌套列表推导式呢?

暂无标签

4 个回答

-1

@brian-putman 的回答更快更好……不过这是我的解决方案:

init = lambda x, y: [init(x, y-1) if y>1 else 0 for _ in xrange(x)]

这个代码只会生成大小为 x 的方阵,里面全是零,适用于 y 个维度。使用方法如下:

init(5, 3)

[[[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]],
 [[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]],
 [[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]],
 [[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]],
 [[0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0]]]
-1

我同意,如果可以使用numpy,那处理矩阵会简单很多。我强烈推荐使用它。

不过,使用这个递归函数也是一个不错的方法,可以让你的代码适应多维度。第一个参数是一个列表或元组,用来指定每个维度的大小(间接地,也说明了有多少个维度)。第二个参数是用来填充矩阵的常量值(在你的例子中是0):

def init(sizes, value=0):
    if (len(sizes) == 1):
        return [value] * sizes[0]
    else:

        # old code - fixed per comment. This method does not create
        # sizes[0] *new* lists, it just repeats the same list
        # sizes[0] times. This causes unexpected behavior when you
        # try to set an item in a list and all of its siblings get
        # the same change
        # return [init(sizes[1:], value)] * sizes[0]

        # this method works better; it creates a new list each time through
        return [init(sizes[1:], value) for i in xrange(sizes[0])]

matrix = init((2,3,4), 5)
matrix[0][0][0] = 100 # setting value per request in comment
print matrix
>>> [[[100, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]], [[5, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]]]

N维数组在二维屏幕上打印起来有点困难,但在下面这个我手动缩进的代码片段中,你可以更清楚地看到matrix的结构。它是一个长度为2的数组,里面包含长度为3的数组,而这些数组又包含长度为4的数组,每个值都被设置为5:

[
    [
        [100, 5, 5, 5],
        [5, 5, 5, 5],
        [5, 5, 5, 5]
    ],
    [
        [5, 5, 5, 5],
        [5, 5, 5, 5],
        [5, 5, 5, 5]
    ]
]
0

如果你真的想要一个矩阵,可以使用 np.zerosnp.ones 快速创建一个二维数组来表示矩阵:

import numpy as np
my_matrix = np.matrix(np.zeros((10,10)))

如果想要扩展到n维,就不能再用矩阵了,因为矩阵的定义就是二维的:

n_dimensions = 3
width = 10

n_dimensional_array = np.ones((width,) * n_dimensions)
0

因为整数是不可改变的,你可以把你的代码简化成:

matrix = [[0] * 10 for x in range(10)]

正如@iCodez在评论中提到的,如果你可以使用NumPy的话,你可以简单地这样做:

import numpy as np                                              
matrix = np.zeros((10, 10)) 

撰写回答