permutation of elements inside the list of list - python

I have a nested list as follows:
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
I need to permute only the elements inside each list.
do you have any idea how can I do this?

You can do something like this:
import random
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for x in A:
random.shuffle(x)

To shuffle each sublist in a list comprehension, you cannot use random.shuffle because it works in place. You can use random.sample with the sample length = the length of the list:
import random
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_a = [random.sample(l,len(l)) for l in A]
print(new_a)
an output:
[[2, 1, 3], [5, 4, 6], [7, 9, 8]]
That solution is the best one if you don't want to modify your original list. Else, using shuffle in a loop as someone else answered works fine as well.

Use permutations from itertools:
from itertools import permutations
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
out = []
for i in A:
for j in permutations(i):
out.append(list(j))
print out
OUTPUT:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1],
[4, 5, 6], [4, 6, 5], [5, 4, 6], [5, 6, 4], [6, 4, 5], [6, 5, 4],
[7, 8, 9], [7, 9, 8], [8, 7, 9], [8, 9, 7], [9, 7, 8], [9, 8, 7]]

Related

Remove 2 duplicated swap sublists in list

I have a two-dimensional list like this:
[[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
I want to remove all the sublists that are duplicates but in reverse order (ie: [1, 6] and [6, 1], [3, 7] and [7, 3]).
The result should be:
[[1, 6], [2, 5], [3, 7], [8, 9]]
You can use set and frozenset:
lst = [[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
output = set(map(frozenset, lst))
print(output)
# {frozenset({1, 6}), frozenset({2, 5}), frozenset({3, 7}), frozenset({8, 9})}
If you want to have a list of lists, then you can append the following:
output = list(map(list, output))
print(output)
# [[1, 6], [2, 5], [3, 7], [8, 9]]
You can do this easily by checking if the sorted list is already had already been added. Like this:
data = [[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
new_data = []
for lst in data:
if sorted(lst) not in new_data:
new_data.append(lst)
print(new_data) # => [[1, 6], [2, 5], [3, 7], [8, 9]]
This works because [1, 6] and [6, 1] return the same sorted list.

Python: Flattening an index by only one level [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 2 years ago.
I'm aware of how completely flattening a list of sublists is done, however, I am unsure of how to do so by only one level.
For example, a sublist like [[[1, 2], 3], [[4, 5], 6], [[7, 8], 9]] would get flattened into [1, 2, 3, 4, 5, 6, 7, 8, 9].
However, I'm struggling to figure out a way for the result to be [[1, 2, 3], [4, 5, 6], [7, 8, 9]], without ending up flattening the entire list.
Any help will be appreciated!
input_array = [([1, 2], 3), [[4, 5], 6], [[7, 8, (9, [10])], 11]]
result_array = []
def flat_element(el):
global result_array
_class = ''
try:
_class = str(type(el)).split("'")[1]
except:
pass
if _class in ('list', 'tuple'):
for elem in el:
flat_element(elem)
else:
result_array.append(el)
flat_element(input_array)
print(result_array)
main_array = []
for sub_array in input_array:
result_array = []
flat_element(sub_array)
main_array.append(result_array)
print(main_array)
example_array = [[[1, 2], 3], [[4, 5], 6], [[7, 8], 9]]
main_array = []
for sub_array in example_array:
result_array = []
flat_element(sub_array)
main_array.append(result_array)
print(main_array)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[[1, 2, 3], [4, 5, 6], [7, 8, 9, 10, 11]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Working with arrays and tuples

Combination of few list with keeping order

I have a few lists that I want to make combinations the output should have the first item from list1 second from list2 and last from list3.
I tried with for and append but it did not work can itertools be used?
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8 ,9]
Output should be
[[1,4,7],[2,4,7]...[3,6,9]]
You can also try considering simple list comprehension. What makes your question unique is the order of elements. The key point here is to have list1 as the inner most loop just to have the output in the order you want.
result = [[i, j, k] for k in list3 for j in list2 for i in list1]
Output
[[1, 4, 7],
[2, 4, 7],
[3, 4, 7],
[1, 5, 7],
[2, 5, 7],
[3, 5, 7],
[1, 6, 7],
[2, 6, 7],
[3, 6, 7],
[1, 4, 8],
[2, 4, 8],
[3, 4, 8],
[1, 5, 8],
[2, 5, 8],
[3, 5, 8],
[1, 6, 8],
[2, 6, 8],
[3, 6, 8],
[1, 4, 9],
[2, 4, 9],
[3, 4, 9],
[1, 5, 9],
[2, 5, 9],
[3, 5, 9],
[1, 6, 9],
[2, 6, 9],
[3, 6, 9]]
You can use numpy
print([list(x) for x in numpy.array(numpy.meshgrid(list1,list2,list3)).T.reshape(-1,len(a))])
Outputs:
[[1, 4, 7], [1, 5, 7], [1, 6, 7], [2, 4, 7], [2, 5, 7], [2, 6, 7], [3, 4, 7], [3, 5, 7], [3, 6, 7], [1, 4, 8], [1, 5, 8], [1, 6, 8], [2, 4, 8], [2, 5, 8], [2, 6, 8], [3, 4, 8], [3, 5, 8], [3, 6, 8], [1, 4, 9], [1, 5, 9], [1, 6, 9], [2, 4, 9], [2, 5, 9], [2, 6, 9], [3, 4, 9], [3, 5, 9], [3, 6, 9]]

Why is my original 2D array being modified in the following code

Im trying to solve a coding problem where i have to generate some matrices, im new to python and i cant figure out why my matrix keeps getting changed to the latest matrix being generated. Here's the code i have so far:
def mirrorHorizontal(m):
l = list(m)
matrix_len = len(l)
for x in range(0,matrix_len):
temp = l[x][matrix_len-1]
l[x][matrix_len-1] = l[x][0]
l[x][0] = temp
return l
def mirrorVertical(m):
l = list(m)
matrix_len = len(l)
for x in range(0,matrix_len):
temp = l[0][x]
l[0][x] = l[matrix_len-1][x]
l[matrix_len-1][x] = temp
return l
def rotateMatrix(m):
l = list(m)
matrix_len = len(l)
rotated_matrix = []
for x in range(0,matrix_len):
rotated_row = []
for y in range(0, matrix_len):
rotated_row.append([(matrix_len-1) -y][y])
rotated_matrix.append(rotated_row)
return rotated_matrix
# Complete the formingMagicSquare function below.
def formingMagicSquare(s):
all_matrices = []
base_matrix = [[8,3,4],[1,5,9],[6,7,2]]
all_matrices.append(base_matrix)
print("all matrices after first append",all_matrices)
base_h_mirror = list(mirrorHorizontal(base_matrix))
print("horizontal_mirror",base_h_mirror)
all_matrices.append(base_h_mirror)
print("all matrices after first h mirror append",all_matrices)
base_v_mirror = list(mirrorVertical(base_matrix))
print("vertical_mirror",base_v_mirror)
all_matrices.append(base_v_mirror)
print("all matrices after first v mirror append",all_matrices)
#Same as vertical mirror of horizontal mirror
base_v_h_mirror = list(mirrorHorizontal(base_v_mirror))
all_matrices.append(base_h_mirror)
print("h_mirror added",all_matrices)
all_matrices.append(base_v_mirror)
print("h_mirror added",all_matrices)
all_matrices.append(base_v_h_mirror)
print("base_v_h_mirror added",all_matrices)
print("mirrored matrices= ",all_matrices)
matrix_len = len(all_matrices)
for x in range(0,matrix_len):
all_matrices.append(rotateMatrix(all_matrices[x]))
print(all_matrices)
formingMagicSquare()
The output , if you run it is something like:
all matrices after first append [[[8, 3, 4], [1, 5, 9], [6, 7, 2]]]
horizontal_mirror [[4, 3, 8], [9, 5, 1], [2, 7, 6]]
all matrices after first h mirror append
[
[[4, 3, 8], [9, 5, 1], [2, 7, 6]],
[[4, 3, 8], [9, 5, 1], [2, 7, 6]]
]
vertical_mirror [[2, 7, 6], [9, 5, 1], [4, 3, 8]]
all matrices after first v mirror append
[[[2, 7, 6], [9, 5, 1], [4, 3, 8]],
[[2, 7, 6], [9, 5, 1], [4, 3, 8]],
[[2, 7, 6], [9, 5, 1], [4, 3, 8]]]
h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
base_v_h_mirror added [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
mirrored matrices= [[[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]]]
Why is my matrix being populated with the same matrix again and again? I converted the list in the functions i used by slicing it [:]
This is also related to mutable and immutable types. You are dealing with lists of lists, which are lists of mutables. So the inner lists are passed by reference, even if you use [:] which makes a shallow copy: a copy of the container, but holding references to the inner object if they are mutables.
That's why, when you change the inner lists, you are changing the same inner lists each time. They are all references to the same lists.
Have a look at the copy docs to more details about shallow copies and deep copies. This will also give you a solution: use a deep copy.
In each function, replace:
l = list(m)
with:
l = copy.deepcopy(m)

numpy optimize way(remove loops)

I want to use this code on very huge array. this code take long time to execute and it is not efficient.
is there any way to remove loop and convert this code to optimum way?
>>> import numpy as np
>>> x=np.random.randint(10, size=(4,5,3))
>>> x
array([[[3, 2, 6],
[4, 6, 6],
[3, 7, 9],
[6, 4, 2],
[9, 0, 1]],
[[9, 0, 4],
[1, 8, 9],
[6, 8, 1],
[9, 4, 5],
[1, 5, 2]],
[[6, 1, 6],
[1, 8, 8],
[3, 8, 3],
[7, 1, 0],
[7, 7, 0]],
[[5, 6, 6],
[8, 3, 1],
[0, 5, 4],
[6, 1, 2],
[5, 6, 1]]])
>>> y=[]
>>> for i in range(x.shape[1]):
for j in range(x.shape[2]):
y.append(x[:, i, j].tolist())
>>> y
[[3, 9, 6, 5], [2, 0, 1, 6], [6, 4, 6, 6], [4, 1, 1, 8], [6, 8, 8, 3], [6, 9, 8, 1], [3, 6, 3, 0], [7, 8, 8, 5], [9, 1, 3, 4], [6, 9, 7, 6], [4, 4, 1, 1], [2, 5, 0, 2], [9, 1, 7, 5], [0, 5, 7, 6], [1, 2, 0, 1]]
You could permute axes with np.transpose and then reshape to 2D -
y = x.transpose(1,2,0).reshape(-1,x.shape[0])
Append with .tolist() for list output.
yes, either use np.reshape(x, shape) or try it with np.ndarray.flatten(x, order='F') (F for Fortran style, column first, according to your example).
read the documentation to find out which parameters fit the best. IMHO, I think ndarray.flatten is the better and more elegant option for you here. However, depending on your exact wanted solution, you might have to reshape the array first.

Categories

Resources