Sorting multidimensional array in python - python

Let say I have an array of
x = [[5, 9, 7, 17, 13, 0], [8, 10, 16, 35, 7, 5], [10, 17, 5]]
I want to sort the value so that it will look like this:
x = [[0, 5, 5, 5, 7, 7], [8, 9, 10, 10, 13, 16], [17, 17, 35]]
How could I achieve this?

code:
x = [[5, 9, 7, 17, 13, 0], [8, 10, 16, 35, 7, 5], [10, 17, 5]]
y = sorted(sum([i for i in x],[]))
result = []
for i in x:
temp = []
for j in range(len(i)):
temp.append(y.pop(0))
result.append(temp)
print(result)
result:
[[0, 5, 5, 5, 7, 7], [8, 9, 10, 10, 13, 16], [17, 17, 35]]

The best answer is given by #leaf_yakitori please look at it. Now I just added this code to reduce time complexity from O(n^2) to O(n)
x = [[5, 9, 7, 17, 13, 0], [8, 10, 16, 35, 7, 5], [10, 17, 5]]
y = sorted(sum([i for i in x],[]))
result = []
ind = 0
for i in x:
result.append(y[ind:ind + len(i)])
ind += len(i)
print(result)

Related

How do I put data in a two-dimensional array sequentially without duplication?

I want to put data consisting of a one-dimensional array into a two-dimensional array. I will assume that the number of rows and columns is 5.
The code I tried is as follows.
data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
a = []
for i in range(5):
a.append([])
for j in range(5):
a[i].append(j)
print(a)
# result : [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
# I want this : [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20]]
You don't have to worry about the last [20].
The important thing is that the row must change without duplicating the data.
I want to solve it, but I can't think of any way. I ask for your help.
There are two issues with the current code.
It doesn't actually use any of the values from the variable data.
The data does not contain enough items to populate a 5x5 array.
After adding 0 to the beginning of the variable data and using the values from the variable, the code becomes
data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
a = []
for i in range(5):
a.append([])
for j in range(5):
if i*5+j >= len(data):
break
a[i].append(data[i*5+j])
print(a)
The output of the new code will be
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20]]
This should deliever the desired output
data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
a = []
x_i = 5
x_j = 5
for i in range(x_i):
a.append([])
for j in range(x_j):
a[i].append(i*x_j+j)
print(a)
Output:
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]]
By using list comprehension...
data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
columns = 5
rows = 5
result = [data[i * columns: (i + 1) * columns] for i in range(rows)]
print(result)
# [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20]]
You could use itertools.groupby with an integer division to create the groups
from itertools import groupby
data = [0, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
grouped_data = [list(v) for k, v in groupby(data, key=lambda x: x//5)]
print(grouped_data)
Output
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20]]

Counter of iterations in comprehension list with nested loops

X =[
[2, 10, 3, 1],
[4, 2, 0, 7],
[6, 9, 6, 9],
[1, 3, 4, 5]
]
Y =[
[4, 2, 3, 1],
[9, 9, 9, 7],
[1, 2, 3, 4],
[5, 6, 7, 8]
]
So i have to add these two matrixes. I solved it, but i have to create counter of iterations.
def summary(X, Y):
return [X[i][j] + Y[i][j] for j in range(len(X[0]))] for i in range(len(X))]
I was searching for the solution and also trying to figure it out by myself, but i have no idea what to do if there is already two loops inside this list.
Desired output:
[6, 12, 6, 2]
[13, 11, 9, 14]
[7, 11, 9, 13]
[6, 9, 11, 13]
number of iterations: 16
import numpy as np
np.reshape(np.array(X) + np.array(Y), (4,4)).tolist()
# output
# [[6, 12, 6, 2], [13, 11, 9, 14], [7, 11, 9, 13], [6, 9, 11, 13]]
You can use a nested list comprehension to do element-wise addition
>>> [[i+j for i,j in zip(a, b)] for a,b in zip(X,Y)]
[[6, 12, 6, 2],
[13, 11, 9, 14],
[7, 11, 9, 13],
[6, 9, 11, 13]]
In general (unless this is a learning exercise) I'd suggest using numpy as it is significantly faster for linear algebra operations
>>> import numpy as np
>>> np.array(X) + np.array(Y)
array([[ 6, 12, 6, 2],
[13, 11, 9, 14],
[ 7, 11, 9, 13],
[ 6, 9, 11, 13]])
If you wanted to do this "by hand" while keeping a counter you could do something like
def add(X,Y):
ops = 0
result = []
for a, b in zip(X,Y):
row = []
for i,j in zip(a, b):
row.append(i + j)
ops += 1
result.append(row)
print('number of iterations: {}'.format(ops))
return result
>>> add(X, Y)
number of iterations: 16
[[6, 12, 6, 2], [13, 11, 9, 14], [7, 11, 9, 13], [6, 9, 11, 13]]

How to find all possible ascending and descending order from a list?

I have a list of number:
number = [1,2,3,4,5,6,...,20]
I would like to generate all possible ascending and descending order of 6 total from my list.
possible_ordered:
[1,2,3,4,5,6]
[2,3,4,5,6,7]
[3,4,5,6,7,8]
...
[15,16,17,18,19,20]
[20,19,18,17,16,15]
[15,14,13,12,11,10]
[10,9,8,7,6,5]
[6,5,4,3,2,1]
This is what I tried so far.
a = [1,2,3,4,5,6,7,8,9,10]
for x in a:
b = a[a.index(x):a.index(x)+6]
if len(b) == 6:
print b
output:
[1, 2, 3, 4, 5, 6]
[2, 3, 4, 5, 6, 7]
[3, 4, 5, 6, 7, 8]
[4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9, 10]
I don't know how to get the descending order and I'm not really sure this is a good code.
Try this:
a = list(range(1, 21))
b = list(range(20, 0, -1)) # the revers of a
print([a[start: start + 6] for start in range(len(a) - 5)] +
[b[start: start + 6] for start in range(len(a) - 5)])
Output:
[[1, 2, 3, 4, 5, 6],
[2, 3, 4, 5, 6, 7],
[3, 4, 5, 6, 7, 8],
[4, 5, 6, 7, 8, 9],
[5, 6, 7, 8, 9, 10],
[6, 7, 8, 9, 10, 11],
[7, 8, 9, 10, 11, 12],
[8, 9, 10, 11, 12, 13],
[9, 10, 11, 12, 13, 14],
[10, 11, 12, 13, 14, 15],
[11, 12, 13, 14, 15, 16],
[12, 13, 14, 15, 16, 17],
[13, 14, 15, 16, 17, 18],
[14, 15, 16, 17, 18, 19],
[15, 16, 17, 18, 19, 20],
[20, 19, 18, 17, 16, 15],
[19, 18, 17, 16, 15, 14],
[18, 17, 16, 15, 14, 13],
[17, 16, 15, 14, 13, 12],
[16, 15, 14, 13, 12, 11],
[15, 14, 13, 12, 11, 10],
[14, 13, 12, 11, 10, 9],
[13, 12, 11, 10, 9, 8],
[12, 11, 10, 9, 8, 7],
[11, 10, 9, 8, 7, 6],
[10, 9, 8, 7, 6, 5],
[9, 8, 7, 6, 5, 4],
[8, 7, 6, 5, 4, 3],
[7, 6, 5, 4, 3, 2],
[6, 5, 4, 3, 2, 1]]

Split a list with consecutive block items but discontinued blocks into sub-lists

Suppose I have a list like this:
mylist = [2,3,4,7,8,9,0,1,2,3,10,11,12,20,19,18,17,17,18,19,20,21]
I want to split it into sub-lists like this:
sublist_1 = [2,3,4]
sublist_2 = [7,8,9]
sublist_3 = [0,1,2,3]
sublist_4 = [10,11,12]
sublist_5 = [20,19,18,17]
sublist_5 = [17,18,19,20,21]
How can I do this?
Code -
mylist = [2, 3, 4, 7, 8, 9, 0, 1, 2, 3, 10, 11, 12, 20, 19, 18, 17, 17, 18, 19,
20, 21]
result = []
temp_list = [mylist[0]]
for i in range(1, len(mylist)):
if abs(mylist[i] - mylist[i - 1]) != 1:
result.append(temp_list)
temp_list = [mylist[i]]
else:
temp_list.append(mylist[i])
if temp_list:
result.append(temp_list)
print(result)
Output -
[[2, 3, 4], [7, 8, 9], [0, 1, 2, 3], [10, 11, 12], [20, 19, 18, 17],
[17, 18, 19, 20, 21]]
This would do;
mylist = [2,3,4,7,8,9,0,1,2,3,10,11,12,20,19,18,17,17,18,19,20,21]
index =0
for i in range(0, len(mylist)):
#print (mylist[i+1])
if (i+1 >= len(mylist)):
print (mylist[index:i+1])
break
if not( (mylist[i+1] - mylist[i] == 1) or (mylist[i+1] - mylist[i] == -1) ):
print (mylist[index:i+1])
index = i+1
Output
[2, 3, 4]
[7, 8, 9]
[0, 1, 2, 3]
[10, 11, 12]
[20, 19, 18, 17]
[17, 18, 19, 20, 21]
This is the numpy approach. I'm using ediff1d,
intersect1d, nonzero
import numpy as np
mylist = [2, 3, 4, 7, 8, 9, 0, 1, 2, 3, 10, 11, 12, 20, 19, 18, 17, 17, 18, 19,
20, 21]
a = np.array(mylist)
t = np.ediff1d(mylist)
i = np.intersect1d(np.nonzero(t!=-1), np.nonzero(t!=1))
rslt = np.split(a,i+1)
rslt
Out[70]:
[array([2, 3, 4]),
array([7, 8, 9]),
array([0, 1, 2, 3]),
array([10, 11, 12]),
array([20, 19, 18, 17]),
array([17, 18, 19, 20, 21])]
if you want the output to be list instead of numpy array, change the last line to rslt = [x.tolist() for x in np.split(a,i+1)], the result will be
rslt
Out[9]:
[[2, 3, 4],
[7, 8, 9],
[0, 1, 2, 3],
[10, 11, 12],
[20, 19, 18, 17],
[17, 18, 19, 20, 21]]

Matrix printingPrinting reversed with loops

I'm practicing looping with matrix, but I'm really stuck for an hour.
A = [[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18],
[19, 22, 21, 22, 23, 24]]
Here is my Matrix and basically I'd like to change the loop sens on every line.
I have my function to print only values:
def clearPrint(Matrix):
i = 0
j = 0
result=[]
longLigne = len(Matrix)
longCol = len(Matrix[i])
for i in range(0, longLigne):
print(" ")
for j in range (0, longCol):
result = Matrix[i][j]
print(result, end=" ")
And when it comes to switch the reverse the loop, I have no idea how..
And here is the result I'm trying to get
A = [[1, 2, 3, 4, 5, 6],
[12, 11, 10, 9, 8, 7],
[13, 14, 15, 16, 17, 18],
[24, 23, 22, 21, 20, 19]]
Any advice, would be helpful
One-liner:
A = [v[::-1] if i % 2 == 1 else v for i, v in enumerate(A)]
a = [[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18],
[19, 22, 21, 22, 23, 24]]
for x in a:
if a.index(x) % 2 != 0:
print (x[::-1])
else:
print (x)
Output;
[1, 2, 3, 4, 5, 6]
[12, 11, 10, 9, 8, 7]
[13, 14, 15, 16, 17, 18]
[24, 23, 22, 21, 22, 19]
>>>
[::-1] will reverse the lists.
Another potential method:
def clearPrint(Matrix):
for i in range(0, len(Matrix)):
if i % 2 != 0:
print(list(reversed(Matrix[i])))
else:
print(Matrix[i])
A = [[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18],
[19, 22, 21, 22, 23, 24]]
clearPrint(A)

Categories