confused_programmer
confused_programmer

Reputation: 59

List manipulation in Python (matrix as a list of list)

I want to define a function called "create_matrix" that first creates an l1+1 by l2+1 matrix of zeros (implemented as a list of list; NOT numpy). Next, the function should set the first row to be [0, 1, 2, ..., l2], and the first column to be [0, 1, 2, ..., l1].

However, running the function create_matrix(7,8) returns the following matrix (see picture), which is not expected. Could you please tell me why?

enter image description here

def create_matrix(l1, l2):
    matrix = [[0]*(l2+1)]*(l1+1)
    matrix[0] =  [i for i in range(0,l1+2)]
    counter = 0 
    for inner_list in matrix:
        inner_list[0] = counter 
        counter += 1 
    return matrix
create_matrix(7,8)

Upvotes: 0

Views: 145

Answers (2)

Helios
Helios

Reputation: 715

It is to do with list creation as Ted says in the comment, you are actually copying a pointer to the same list into all the "zero" positions. Just create it directly:

def create_matrix(l1, l2):
    matrix = [list(range(l1 + 2))]
    for i in range(1, l2):
        matrix.append([i] + [0] * (l1 + 1))
    return matrix

or alternatively construct a new list for each row of the matrix

matrix = [[0 for i in range(n1)] for j in range(n2)]

Upvotes: 2

user16004728
user16004728

Reputation:

Here:

matrix = [[0]*(l2+1)]*(l1+1)

You are building a list of l1+1 elements pointing to the same array.

And here:

matrix[0] = [i for i in range(0,l1+2)]

You are changing the first of those elements to point to a different array.

Thus all but the very first value are the same (7) in your output.

You can use something like this instead:

def create_matrix(l1, l2):
    matrix = [[i for i in range(l1+2)]]
    for i in range(1, l2+1):
        matrix.append([i] + [0] * l2)
    return matrix

Upvotes: 0

Related Questions