Below is my script, which basically creates a zero matrix of 12x8 filled with 0. Then I want to fill it in, one by one. So lets say column 2 row 0 needs to be 5. How do I do that? The example below shows how I did it and the wrong (for my needs) output:
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]
To get the length of a 2D Array in Python: Pass the entire array to the len() function to get the number of rows. Pass the first array element to the len() function to get the number of columns. Multiply the number of rows by the number of columns to get the total.
The data elements in a matrix can be accessed by using the indexes. The access method is same as the way data is accessed in Two dimensional array.
Each row points to the same sublist. This is the result of appending the same sublist repeatedly. So when you modify one row, you end up modifying 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]]
An aside about coding style: It is poor form in Python to include the type of the object in its name. I have chosen to rename int_NumbOfColumns
as ncols
. If you need something more descriptive use something like column_count
. Generally, mixedCase names are to be avoided, while CamelCase is generally used for class names. See PEP 8 -- Style Guide for Python Code for more.
Edit: Since you mentioned that you are new to Python, here's a little more explanation.
This is a list comprehension:
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)
Each entry in list_AlignMatrix
is a reference to the same object. You'll need to create a new list
instance for each row in your matrix. Here's an illustration of what's 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 each entry in l2
is a reference to the same object:
>>> [id(x) for x in l2]
[161738316, 161738316, 161738316]
To make new copies of your row list, you can rewrite your second loop like this:
for i in range (0, int_NumbOfRows):
list_AlignMatrix.append(list(list_AlignMatrixRow))
The list
constructor will create copies of list_AlignMatrixRow
, as illustrated by the following example:
>>> l = range(10)
>>> l2 = list(l)
>>> l == l2
True
>>> l is l2
False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With