Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cell assignment of a 2-dimensional Matrix in Python, without numpy

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]
like image 277
StudentOfScience Avatar asked Oct 21 '12 03:10

StudentOfScience


People also ask

How do you find the dimensions of a 2D matrix in Python?

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.

How do you access the elements of a matrix in Python?

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.


2 Answers

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)
like image 111
Steven Rumbalski Avatar answered Nov 11 '22 00:11

Steven Rumbalski


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
like image 44
John Vinyard Avatar answered Nov 11 '22 02:11

John Vinyard