Reputation: 575
Let's consider those two variables :
matrix = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]]
list_of_lengths = [2, 1, 1]
I am looking for a method to get this result :
result = [[[1, 2],
[5, 6],
[9, 10]], [[3],
[7],
[11]], [[4],
[8],
[12]]]
Indeed, I want three matrix as a result. The j-length of each one is determined by the variable list_of_lentghts.
I have already written a solution that works, but I would like to know if there is a solution more simple. Here is my solution:
def cut_matrix(matrix, list_of_lengths):
result = []
for a_len in list_of_lengths:
current_sub_matrix = []
for a_line in matrix:
current_new_line = []
for i in range(0, a_len):
current_new_line.append(a_line.pop(0))
current_sub_matrix.append(current_new_line)
result.append(current_sub_matrix)
return result
Upvotes: 2
Views: 519
Reputation: 476967
If you know the column offset i
and the number of columns n
, you can use slicing to obtain the columns:
[row[i:i+n] for row in matrix]
to get the slice. So you can simply use:
def cut_matrix(matrix, list_of_lengths):
result = []
col = 0
for a_len in list_of_lengths:
result.append([row[col:col+a_len] for row in matrix])
col += a_len
return result
It generates:
>>> cut_matrix(matrix,list_of_lengths)
[[[1, 2], [5, 6], [9, 10]], [[3], [7], [11]], [[4], [8], [12]]]
This will also work faster than using .pop(0)
since popping from the front is done in O(n) (so popping all elements requires O(n2) whereas slicing all elements is done in O(n)). Finally it leaves the original matrix
intact which is thus more declarative.
Upvotes: 2