11

I'm using a list of lists to store a matrix in python. I tried to initialise a 2x3 Zero matrix as follows.

mat=[[0]*2]*3

However, when I change the value of one of the items in the matrix, it changes the value of that entry in every row, since the id of each row in mat is the same. For example, after assigning

mat[0][0]=1

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

I know I can create the Zero matrix using a loop as follows,

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

but can anyone show me a more pythonic way?

1
  • There should be one-- and preferably only one --obvious way to do it. ;-) Commented May 28, 2009 at 21:06

8 Answers 8

9

Use a list comprehension:

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

Or, as a function:

def matrix(rows, cols):
    return [[0]*cols for x in xrange(rows)]
Sign up to request clarification or add additional context in comments.

Comments

8

Try this:

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

This is also discussed 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]]

2 Comments

+1 - nice stuff. I'm just learning Python, so I greatly appreciate seeing snippets of "pythonic" code.
"[0]*rows" part is misleading; you're creating a list that is not used in any way except its length. Use either xrange(n) or (less likely) itertools.repeat(None, n) to do something n times in Python.
7

This one is faster than the accepted answer!
Using xrange(rows) instead of [0]*rows makes no difference.

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

A variation that doesn't use itertools and runs around the same speed

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

From 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

Comments

4

I use

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

although depending on what you do with the matrix after you create it, you might take a look at using a NumPy array.

1 Comment

I'm going to explore NumPy at some point, but for my current problem, a list of list is enough.
3

This will work

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

Comments

2

What about:

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; from the 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.

Comments

2

If the sizes involved are really only 2 and 3,

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

is easily best and hasn't been mentioned yet.

Comments

1

Is there anything itertools can't do? :)

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.