Scylla
Scylla

Reputation: 33

Convert a list to a matrix

I want to convert a list with numbers to a matrix. This is my code:

   def converttomtx(mylist, rows, columns):
       mtx = []
       for r in range(rows):
           lrow = []
           for c in range(columns):
               lrow.append(mylist[rows * r + c])
           mtx.append(lrow)
       return mtx

Assuming I use the following list: l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

The code works if I set the rows to 3 and columns to 4, but when I set rows to 4 and columns to 3 then it throws an error that the list index is out of range. I cannot see why. The same happens when I use 2x6 and 6x2, 2x6 works but 6x2 doesn't.

Upvotes: 2

Views: 86

Answers (5)

Circuit Planet
Circuit Planet

Reputation: 181

You just used the wrong formula for index in line 6.

Instead of mylist[rows * r + c]

It should be mylist[columns * r + c]

after this your code would look like:

def converttomtx(mylist, rows, columns):
       mtx = []
       for r in range(rows):
           lrow = []
           for c in range(columns):
               lrow.append(mylist[columns * r + c])
           mtx.append(lrow)
       return mtx

Upvotes: 0

keithpjolley
keithpjolley

Reputation: 2263

Another approach:

def l2m(mylist, rows, cols):
    if len(mylist) != rows * cols:
        print('wrong shape')
        return
    return [mylist[row*cols:(row+1)*cols] for row in range(rows)]


mylist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

print(l2m(mylist, 12, 1))
print(l2m(mylist, 3, 4))
print(l2m(mylist, 9, 3)

This returns:

[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]]
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
wrong shape
None

Upvotes: 0

Mr. Hobo
Mr. Hobo

Reputation: 552

You can try the robust numpy library for any type of list reshaping, for example:

>>> import numpy as np
>>> li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> li = np.array(li) # convert to an ndarray

>>> li.reshape(2, 6)
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

>>> li.reshape(6, 2)
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])

Let's assume, you don't know any of the dimensions you can also use: li.reshape(3, -1) which will compute the dimension for you.

>>> li.reshape(3, -1)
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Upvotes: 1

Jay
Jay

Reputation: 2471

The issue is with how you are calculating the index of the list item to be inserted in the matrix, rows * r + c would be more than 11 if rows = 6 for example, so it should be columns * r + c or rows * c + r

You can try printing columns * r + c and rows * r + c in your for loop for understanding the bug in your original solution.

Here's the updated code -

def converttomtx(mylist, rows, columns):
   mtx = []
   for r in range(rows):
       lrow = []
       for c in range(columns):
           lrow.append(mylist[columns * r + c])  # updated
       mtx.append(lrow)
   return mtx

print(converttomtx([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 2, 6))

Output:

[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]

For

print(converttomtx([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 6, 2))

Output:

[[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]

Upvotes: 0

Yevhen Kuzmovych
Yevhen Kuzmovych

Reputation: 12140

mylist[rows * r + c] should be mylist[columns * r + c] as columns is the correct offset in mylist.

Upvotes: 0

Related Questions