2009-05-28 71 views
10

我使用列表的列表在python中存儲矩陣。我試圖初始化如下的2x3零矩陣。以pythonic的方式創建列表的列表

mat=[[0]*2]*3 

然而,當我改變了基質的項目之一的值,它改變了一行項的值,因爲每行的mat的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的方式?

+0

應該有一個 - 最好只有一個 - 明顯的方法來做到這一點。 ;-) – Ubiquitous 2009-05-28 21:06:41

回答

9

使用list comprehension

>>> 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)] 
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]] 

這也是討論in this answer

>>> 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]] 
+0

謝謝,那就是我一直在尋找的! – Alasdair 2009-05-28 21:04:36

+0

+1 - 不錯的東西。我只是在學習Python,所以我非常感謝看到「pythonic」代碼片段。 – duffymo 2009-05-28 21:04:51

3

這將工作

col = 2 
row = 3 
[[0] * col for row in xrange(row)] 
2

什麼:

m, n = 2, 3 
>>> A = [[0]*m for _ in range(n)] 
>>> A 
[[0, 0], [0, 0], [0, 0]] 
>>> A[0][0] = 1 
[[1, 0], [0, 0], [0, 0]] 

Aka List comprehension;從docs

List comprehensions provide a concise way to create lists 
without resorting to use of  
map(), filter() and/or lambda. 
The resulting list definition tends often to be clearer  
than lists built using those constructs. 
4

我用

mat = [[0 for col in range(3)] for row in range(2)] 

雖然取決於你做什麼與矩陣創建後,你可以看看使用NumPy數組。

1

另請參閱this question泛化爲n級嵌套列表/ n維矩陣。

1

itertools不能做什麼嗎? :)

>>> from itertools import repeat,izip 
>>> rows=3 
>>> cols=6 
>>> A=map(list,izip(*[repeat(0,rows*cols)]*cols)) 
>>> 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]] 
6

這一個比接受的答案更快!
使用xrange(行)而不是[0] *行沒有區別。

>>> 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 
2

如果所涉及的大小真的只有2和3,

mat = [[0, 0], [0, 0], [0, 0]] 

很容易最好,並hasn尚未提及。

相關問題