以Pythonic方式创建列表的列表

11 投票
8 回答
1447 浏览
提问于 2025-04-15 11:54

我在用Python创建一个矩阵,使用的是列表的列表。我尝试初始化一个2行3列的零矩阵,代码如下:

mat=[[0]*2]*3

但是,当我改变矩阵中某个元素的值时,发现每一行的那个元素的值都跟着变了,因为每一行的ID是一样的。举个例子,当我赋值后,

mat[0][0]=1

mat变成了[[1, 0], [1, 0], [1, 0]]

我知道可以用循环来创建零矩阵,代码如下:

mat=[[0]*2]
for i in range(1,3):
    mat.append([0]*2)

但有没有人能教我一个更符合Python风格的方法呢?

8 个回答

7

这个方法比被接受的答案要快!
用xrange(rows)代替[0]*rows其实没有什么区别。

>>> from itertools import repeat
>>> rows,cols = 3,6
>>> a=[x[:] for x in repeat([0]*cols,rows)]

这是一个不使用itertools的变种,速度差不多。

>>> a=[x[:] for x in [[0]*cols]*rows]

来自ipython:

In [1]: from itertools import repeat

In [2]: rows=cols=10

In [3]: timeit a = [[0]*cols for _ in [0]*rows]
10000 loops, best of 3: 17.8 us per loop

In [4]: timeit a=[x[:] for x in repeat([0]*cols,rows)]
100000 loops, best of 3: 12.7 us per loop

In [5]: rows=cols=100

In [6]: timeit a = [[0]*cols for _ in [0]*rows]
1000 loops, best of 3: 368 us per loop

In [7]: timeit a=[x[:] for x in repeat([0]*cols,rows)]
1000 loops, best of 3: 311 us per loop
8

试试这个:

>>> cols = 6
>>> rows = 3
>>> a = [[0]*cols for _ in [0]*rows]
>>> a
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
>>> a[0][3] = 2
>>> a
[[0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]

这个内容在这个回答中也有讨论

>>> lst_2d = [[0] * 3 for i in xrange(3)]
>>> lst_2d
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> lst_2d[0][0] = 5
>>> lst_2d
[[5, 0, 0], [0, 0, 0], [0, 0, 0]]
9

使用一种叫做列表推导式的方法:

>>> mat = [[0]*2 for x in xrange(3)]
>>> mat[0][0] = 1
>>> mat
[[1, 0], [0, 0], [0, 0]]

或者,可以用一个函数来实现:

def matrix(rows, cols):
    return [[0]*cols for x in xrange(rows)]

撰写回答