以pythonic方式创建列表列表

Ala*_*air 11 python list matrix

我正在使用列表列表来存储python中的矩阵.我尝试按如下方式初始化2x3 Zero矩阵.

mat=[[0]*2]*3
Run Code Online (Sandbox Code Playgroud)

但是,当我更改矩阵中某个项的值时,它会更改每一行中该条目的值,因为行的id mat是相同的.例如,在分配之后

mat[0][0]=1
Run Code Online (Sandbox Code Playgroud)

mat[[1, 0], [1, 0], [1, 0]].

我知道我可以使用循环创建Zero矩阵,如下所示,

mat=[[0]*2]
for i in range(1,3):
    mat.append([0]*2)
Run Code Online (Sandbox Code Playgroud)

但有人能告诉我更多的pythonic方式吗?

Ben*_*ank 9

使用列表理解:

>>> mat = [[0]*2 for x in xrange(3)]
>>> mat[0][0] = 1
>>> mat
[[1, 0], [0, 0], [0, 0]]
Run Code Online (Sandbox Code Playgroud)

或者,作为一个功能:

def matrix(rows, cols):
    return [[0]*cols for x in xrange(rows)]
Run Code Online (Sandbox Code Playgroud)


Pao*_*ino 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]]
Run Code Online (Sandbox Code Playgroud)

这个也在这个答案中讨论:

>>> 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]]
Run Code Online (Sandbox Code Playgroud)

  • "`[0]*行`"部分具有误导性; 你正在创建一个除了长度之外没有以任何方式使用的列表.使用`xrange(n)`或(不太可能)`itertools.repeat(None,n)`在Python中做一些事情. (7认同)

Joh*_*ooy 7

这个比接受的答案快!
使用xrange(行)而不是[0]*行没有区别.

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

不使用itertools并以相同速度运行的变体

>>> a=[x[:] for x in [[0]*cols]*rows]
Run Code Online (Sandbox Code Playgroud)

来自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
Run Code Online (Sandbox Code Playgroud)