Rotating a list of lists - python

m = [[5,9,1,8],
[2,4,5,7],
[6,3,3,2],
[1,7,6,3]]
rotated_map = []
for i in range(len(m[0])):
rotated_map.append([x[i] for x in m])
print(rotated_map)
"""
my result = [[5, 2, 6, 1], [9, 4, 3, 7], [1, 5, 3, 6], [8, 7, 2, 3]]
desired result = [[8,7,2,3],
[1,5,3,6],
[9,4,3,7],
[5,2,6,1]]
"""
I am trying to rotate the list by putting all the last elements first from the lists into one list then the second to last element into another and so on until i get to the first element.

Transpose the list with zip, then reverse it with the [::-1] syntax.
>>> m = [[5, 9, 1, 8], [2, 4, 5, 7], [6, 3, 3, 2], [1, 7, 6, 3]]
>>> list(map(list, zip(*m)))[::-1]
>>> [[8, 7, 2, 3], [1, 5, 3, 6], [9, 4, 3, 7], [5, 2, 6, 1]]
edit:
If you want pretty printing, it's probably easiest to use numpy arrays all the way.
>>> import numpy as np
>>>
>>> m = [[5, 9, 1, 8], [2, 4, 5, 7], [6, 3, 3, 2], [1, 7, 6, 3]]
>>> m = np.array(m)
>>> m
>>>
array([[5, 9, 1, 8],
[2, 4, 5, 7],
[6, 3, 3, 2],
[1, 7, 6, 3]])
>>>
>>> m.T[::-1]
>>>
array([[8, 7, 2, 3],
[1, 5, 3, 6],
[9, 4, 3, 7],
[5, 2, 6, 1]])
Note that m and m.T[::-1] share the same data, because m.T[::-1] is just another view of m. If you need to duplicate the data, use
result = m.T[::-1].copy()

You could use zip, unpacking your list of lists with the *, and inversing the result with [::-1]:
m = [[5,9,1,8],
[2,4,5,7],
[6,3,3,2],
[1,7,6,3]]
res = [list(i) for i in zip(*m)][::-1]
>>> res
[[8, 7, 2, 3], [1, 5, 3, 6], [9, 4, 3, 7], [5, 2, 6, 1]]
If numpy is an option, transposing is easier:
import numpy as np
>>> np.transpose(m)[::-1]
array([[8, 7, 2, 3],
[1, 5, 3, 6],
[9, 4, 3, 7],
[5, 2, 6, 1]])
# or:
>>> np.flip(np.transpose(m),0)
array([[8, 7, 2, 3],
[1, 5, 3, 6],
[9, 4, 3, 7],
[5, 2, 6, 1]])

You can use numpy module to do it. It has the property to transpose the array. Check the below code:
import numpy as np
m = [[5,9,1,8],
[2,4,5,7],
[6,3,3,2],
[1,7,6,3]]
arr = np.array(m).transpose()
new_list = []
for i in range(arr.shape[0]-1,-1,-1):
new_list.append(list(arr[i]))
print(new_list)
Output:
[[8, 7, 2, 3], [1, 5, 3, 6], [9, 4, 3, 7], [5, 2, 6, 1]]

If you want to rotate the list clockwise:
list(map(list, zip(*m[::-1])))
Else, for anti-clockwise:
list(map(list, zip(*m)))[::-1]

use the reverse keyword
result = [[5, 2, 6, 1], [9, 4, 3, 7], [1, 5, 3, 6], [8, 7, 2, 3]]
result.reverse()
print(result)
output:
[[8, 7, 2, 3], [1, 5, 3, 6], [9, 4, 3, 7], [5, 2, 6, 1]]

Related

How to get data out of an array

I have an array as such from a txt file:
[[1, 4, 6, 2, 5]
[3, 4, 3, 5, 4]
[5, 3, 6, 7, 1]]
[[3, 4, 2, 5, 8]
[5, 2, 7, 5, 4]
[4, 2, 4, 4, 0]]
[[2, 5, 3, 1, 4]
[3, 8, 5, 6, 2]
[2, 6, 7, 4, 2]]
I want to take the mean of the 3rd row for each group of results. so each group is in a double bracket [[1, 4, 6, 2, 5]
[3, 4, 3, 5, 4]
[5, 3, 6, 7, 1]] is one group,
[[3, 4, 2, 5, 8]
[5, 2, 7, 5, 4]
[4, 2, 4, 4, 0]] is the second group etc.)
How do I access each group individually?
If you want to take the mean of the third row of each group with:
>>> data[:,2].mean(axis=1)
array([4.4, 2.8, 4.2])
If data is for example:
>>> data
array([[[1, 4, 6, 2, 5],
[3, 4, 3, 5, 4],
[5, 3, 6, 7, 1]],
[[3, 4, 2, 5, 8],
[5, 2, 7, 5, 4],
[4, 2, 4, 4, 0]],
[[2, 5, 3, 1, 4],
[3, 8, 5, 6, 2],
[2, 6, 7, 4, 2]]])
then by slicing, we obtain the third row of each group:
>>> data[:,2]
array([[5, 3, 6, 7, 1],
[4, 2, 4, 4, 0],
[2, 6, 7, 4, 2]])
Then for each row we can calculate the mean with .mean(axis=1)
If your data is like this, This code will work fine
lst =[
[[1, 4, 6, 2, 5],[3, 4, 3, 5, 4],[5, 3, 6, 7, 1]],
[[3, 4, 2, 5, 8],[5, 2, 7, 5, 4],[4, 2, 4, 4, 0]],
[[2, 5, 3, 1, 4],[3, 8, 5, 6, 2],[2, 6, 7, 4, 2]]
]
import numpy as np
means = []
for i in lst:
means.append(np.mean(i[2]))
print(means)
>> [4.4, 2.8, 4.2]

Adding a n extra colum from another matrix

I have these two matrices:
A = [[2, 7, 3, 6], [3, 3, 4, 4], [6, 9, 5, 3], [4, 2, 1, 7]]
B = [[2, 6, 3, 5], [-1, 2, -3, 1], [2, -5, 7, 3]]
I need to create three matrices A+1st column of B, and so on
So I need this final result:
A1 = [[2, 7, 3, 6, 2], [3, 3, 4, 4, 6], [6, 9, 5, 3, 3], [4, 2, 1, 7, 5]]
A2 = [[2, 7, 3, 6, -1], [3, 3, 4, 4, 2], [6, 9, 5, 3, -3], [4, 2, 1, 7, 7]]
A3 = [[2, 7, 3, 6, 2], [3, 3, 4, 4, -5], [6, 9, 5, 3, 7], [4, 2, 1, 7, 3]]
I start doing the following code, but I only got one of those
for j in range(len(B)):
for i in range(j):
b = B[j][i]
A = [x + [b] for x in A]
print(A)
Output:
[[2, 7, 3, 6], [3, 3, 4, 4], [6, 9, 5, 3], [4, 2, 1, 7]]
[[2, 7, 3, 6, -1], [3, 3, 4, 4, -1], [6, 9, 5, 3, -1], [4, 2, 1, 7, -1]]
[[2, 7, 3, 6, -1, 2, -5], [3, 3, 4, 4, -1, 2, -5], [6, 9, 5, 3, -1, 2, -5], [4, 2, 1, 7, -1, 2, -5]]
Process finished with exit code 0
You can leverage enumerate() to get your output:
A = [[2, 7, 3, 6], [3, 3, 4, 4], [6, 9, 5, 3], [4, 2, 1, 7]]
B = [[2, 6, 3, 5], [-1, 2, -3, 1], [2, -5, 7, 3]]
AA ={}
for idx,inner in enumerate(B):
# add to each a from A the k-th elem of your inner
AA[f"A{idx}"] = [a +[inner[k]] for k,a in enumerate(A)]
print(AA) # stored the lists into a dict
{'A0': [[2, 7, 3, 6, 2], [3, 3, 4, 4, 6], [6, 9, 5, 3, 3], [4, 2, 1, 7, 5]],
'A1': [[2, 7, 3, 6, -1], [3, 3, 4, 4, 2], [6, 9, 5, 3, -3], [4, 2, 1, 7, 1]],
'A2': [[2, 7, 3, 6, 2], [3, 3, 4, 4, -5], [6, 9, 5, 3, 7], [4, 2, 1, 7, 3]]}
As a personal preference I avoid using range(len(...)) where I can - enumerate is cleaner.
If string literals do not work for you, use "A{}".format(idx) instead.
Your code does not work because you coupled the range of i to j
for j in range(len(B)): # j starts as 0,1,2
for i in range(j): # i is doing nothing, 0, 0+1 <-- wrong
This is a possible solution that you can certainly start with:
k = len(A)
D = []
for i in range(len(B)):
D.append([])
for j in range(len(A)):
C = A[j][:k]
C.append(B[i][j])
D[i].append(C)
Make sure to use deepcopy so that they are not all referring to the same object.
A = [[2, 7, 3, 6], [3, 3, 4, 4], [6, 9, 5, 3], [4, 2, 1, 7]]
B = [[2, 6, 3, 5], [-1, 2, -3, 1], [2, -5, 7, 3]]
from copy import deepcopy
A_list = [deepcopy(A) for i in range(3)]
for outer_idx, list_in_b in enumerate(B):
for inner_idx, value in enumerate(list_in_b):
A_list[outer_idx][inner_idx].append(value)
print(A_list)
# Output:
#[[[2, 7, 3, 6, 2], [3, 3, 4, 4, 6], [6, 9, 5, 3, 3], [4, 2, 1, 7, 5]],
# [[2, 7, 3, 6, -1], [3, 3, 4, 4, 2], [6, 9, 5, 3, -3], [4, 2, 1, 7, 1]],
# [[2, 7, 3, 6, 2], [3, 3, 4, 4, -5], [6, 9, 5, 3, 7], [4, 2, 1, 7, 3]]]

Delete items in subarrays of a master array

let's say I have the following 3x4 array
master_array = [[1, 3, 4, 5],
[6, 5, 4, 1],
[7, 8, 4, 1]]
Then, I want to delete number 4 from each of the 3 1x4 subarrays. Would I use the following?
for i in range(master_array.shape[0]):
np.delete(master_array[i], 3)
Then, when I print the master_array, would I get?
[[1, 3, 5],
[6, 5, 1],
[7, 8, 1]]
In case master_array is a list of lists, like in your example, you could do
master_array = [[1, 3, 4, 5],
[6, 5, 4, 1],
[7, 8, 4, 1]]
for row in master_array:
del row[2]
In case master_array is indeed a numpy array, you would simply do
master_array = np.array([[1, 3, 4, 5],
[6, 5, 4, 1],
[7, 8, 4, 1]])
np.delete(master_array, 2, axis=1)

How to count the number of sublists based on common elements from a nested list in python?

I have a list of lists like this: [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3], [3, 4]]. How can I count the lists which are sublists of more than two lists? For example, here [2, 3] and [3, 4] would be the lists that are sublists of first 3 lists. I want to get rid of them.
This comprehension should do it:
data = [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3], [3, 4]]
solution = [i for i in data if sum([1 for j in data if set(i).issubset(set(j))]) < 3]
set_list = [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3], [3, 4]]
check_list = [[2, 3], [3, 4]]
sublist_to_list = {}
for set in set_list:
for i, sublist in enumerate(check_list):
count = 0
for element in sublist:
if element in set:
count += 1
if count == len(sublist):
if i not in sublist_to_list:
sublist_to_list[i] = [set]
else:
sublist_to_list[i].append(set)
print(sublist_to_list)
Output: {0: [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3]], 1: [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [3, 4]]}
which means [2, 3] is subset of [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3]]
and [3, 4] is subset of [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [3, 4]]
You can first make a function that gets sub lists of a list:
def sublists(lst):
length = len(lst)
for size in range(1, length + 1):
for start in range(length - size + 1):
yield lst[start:start+size]
Which works as follows:
>>> list(sublists([1, 2, 3, 4, 5]))
[[1], [2], [3], [4], [5], [1, 2], [2, 3], [3, 4], [4, 5], [1, 2, 3], [2, 3, 4], [3, 4, 5], [1, 2, 3, 4], [2, 3, 4, 5], [1, 2, 3, 4, 5]]
Then you can use this to collect all the sublists list indices into a collections.defaultdict:
from collections import defaultdict
lsts = [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7], [2, 3], [3, 4]]
d = defaultdict(list)
for i, lst in enumerate(lsts):
subs = sublists(lst)
while True:
try:
curr = tuple(next(subs))
d[curr].append(i)
except StopIteration:
break
Which will have tuple keys for the sublists, and the list indices as the values.
Then to determine sub lists that occur more than twice in all the lists, you can check if the set of all the indices has a length of more than two:
print([list(k) for k, v in d.items() if len(set(v)) > 2])
Which will give the following sublists:
[[2], [3], [4], [5], [2, 3], [3, 4], [4, 5], [2, 3, 4], [3, 4, 5], [2, 3, 4, 5]]

Unpack items and add a new one

I need to create a new list merging two lists where one of them is a list of lists. Here's what I need to do:
a = [[2, 1, 4, 5, 0], [3, 6, 5, 4, 8], [2, 1, 4, 7, 8], [3, 4, 9, 5, 6], [7, 5, 2, 1, 1]]
b = [2, 3, 5, 0, 8]
c = []
for indx, item in enumerate(a):
c.append([item, b[indx]])
This generates c as:
[[[2, 1, 4, 5, 0], 2], [[3, 6, 5, 4, 8], 3], [[2, 1, 4, 7, 8], 5], [[3, 4, 9, 5, 6], 0], [[7, 5, 2, 1, 1], 8]]
but I would need it to look like:
[[2, 1, 4, 5, 0, 2], [3, 6, 5, 4, 8, 3], [2, 1, 4, 7, 8, 5], [3, 4, 9, 5, 6, 0], [7, 5, 2, 1, 1], 8]
I've tried adding a * in front of item to unpack the elements but that doesn't work.
Just concatenate the items to create a new list from item and the element from b:
for indx, item in enumerate(a):
c.append(item + [b[indx]])
You can simplify your loop using the zip() function:
for a_item, b_item in zip(a, b):
c.append(a_item + [b_item])
Then move the whole definition of c to a list comprehension:
c = [a_item + [b_item] for a_item, b_item in zip(a, b)]
Demo:
>>> a = [[2, 1, 4, 5, 0], [3, 6, 5, 4, 8], [2, 1, 4, 7, 8], [3, 4, 9, 5, 6], [7, 5, 2, 1, 1]]
>>> b = [2, 3, 5, 0, 8]
>>> [a_item + [b_item] for a_item, b_item in zip(a, b)]
[[2, 1, 4, 5, 0, 2], [3, 6, 5, 4, 8, 3], [2, 1, 4, 7, 8, 5], [3, 4, 9, 5, 6, 0], [7, 5, 2, 1, 1, 8]]
You can make use of zip() function and list comprehension:
>>> a = [[2, 1, 4, 5, 0], [3, 6, 5, 4, 8], [2, 1, 4, 7, 8], [3, 4, 9, 5, 6], [7, 5, 2, 1, 1]]
>>> b = [2, 3, 5, 0, 8]
>>> [elem1 + [elem2] for elem1, elem2 in zip(a, b)]
[[2, 1, 4, 5, 0, 2], [3, 6, 5, 4, 8, 3], [2, 1, 4, 7, 8, 5], [3, 4, 9, 5, 6, 0], [7, 5, 2, 1, 1, 8]]

Categories