Assigning cells to a two-dimensional matrix in Python, without numpy

Below is my script, which basically creates a 12x8 null matrix filled with 0. Then I want to fill it one by one. So let's say that the row of column 2 should be equal to 5. How do I do this? The example below shows how I did this and what was wrong (for my needs):

list_MatrixRow = [] list_Matrix = [] #Not to be confused by what the book calls, optimal alignment score matrix int_NumbOfColumns = 12 int_NumbOfRows = 8 for i in range (0, int_NumbOfColumns): # Puts Zeros across the first Row list_AlignMatrixRow.append(0) for i in range (0, int_NumbOfRows): list_AlignMatrix.append(list_AlignMatrixRow) #add the list in another list to make matrix of Zeros #-------------------THE ACTUAL PROBLEMATIC PART; ABOVE IS FINE(It Works)------------ list_AlignMatrix[2][0] = 5 # This is what logically makes sense but here is the output # which happens but I don't want (there should be all 0s and # only one 5 on the cell [2][0]): [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
+6
source share
4 answers

Each row indicates the same sublist. This is the result of re-adding the same sublist. Therefore, when you change one line, you end up changing the others.

I would do this:

 ncols = 12 nrows = 8 matrix = [[0] * ncols for i in range(nrows)] matrix[2][0] = 5 

matrix contains:

 [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

Aside from the coding style. The bad form in Python includes the type of an object in its name. I decided to rename int_NumbOfColumns as ncols . If you need something more descriptive, use something like column_count . As a rule, mixedCase names should be avoided, while CamelCase is usually used for class names. See PEP 8 - Style Guide for Python Code for more information.

Change Since you mentioned that you are new to Python, here are a few more explanations.

This description:

 matrix = [[0] * ncols for i in range(nrows)] 

It can also be written as a regular for loop:

 matrix = [] for i in range(nrows): matrix.append([0] * ncols) 
+8
source

Each entry in list_AlignMatrix is a reference to the same object. You need to create a new list instance for each row in your matrix. Here is an illustration of what is happening:

 >>> l = [0] >>> l2 = [l,l,l] >>> l2 [[0], [0], [0]] >>> l2[0][0] = 1 >>> l2 [[1], [1], [1]] 

You can use the id() function to confirm that every entry in l2 is a reference to the same object:

 >>> [id(x) for x in l2] [161738316, 161738316, 161738316] 

To create new copies of the string list, you can rewrite your second loop as follows:

 for i in range (0, int_NumbOfRows): list_AlignMatrix.append(list(list_AlignMatrixRow)) 

The list constructor will create copies of list_AlignMatrixRow , as shown in the following example:

 >>> l = range(10) >>> l2 = list(l) >>> l == l2 True >>> l is l2 False 
+5
source

When you add list_AlignMatrixRow , it just adds a link to the source list, so there really is one one-dimensional list, and each row of your matrix points to it. To create a new list, you need to create a new list:

 list_AlignMatrix.append(list(list_AlignMatrixRow)) 

Notice the call to the list that creates the list by iterating and copying list_AlignMatrixRow elements

+1
source

in order to generate such a matrix, in python, you must use the comprihention list, as if you want to create a row with all 0,

 >>> import copy >>> list_MatrixRow=[0 for i in range(12)] >>> list_MatrixRow [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

so you can create a list of the list in the same way

list_Matrix = [[0 for j in range (12)] for i in range (8)]

now you can edit any elements

 >>> list_Matrix[0][2]=12345 >>> list_Matrix[0][2] 12345 >>> list_Matrix [[0, 0, 12345, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

if you want to create a matrix containing all columns of 5, you can use a short circuit estimate when understanding the list

 >>> list_MatrixRow=[(i==0 and 5 or 0) for i in range(12)] >>> list_MatrixRow [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >>> list_Matrix=[list_MatrixRow for i in range(8)] >>> list_MatrixRow [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >>> list_Matrix [[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] >>> list_Matrix[0][0] 5 
+1
source

All Articles