Creating an array with unique rows and columns - python

How do I create an array with unique rows and columns like this one in python?
[1, 2, 3, 4]
[2, 3, 4, 1]
[4, 1, 2, 3]
[3, 4, 1, 2]

from itertools import permutations
from random import choice
>>> a = list(permutations([1,2,3,4], 4))
>>> total = [choice(a) for i in range(4)]
>>> total
[(3, 4, 1, 2), (4, 1, 2, 3), (2, 1, 4, 3), (1, 2, 3, 4)]
>>> print(*(' '.join(map(str, item)) for item in total), sep='\n')
3 4 1 2
4 1 2 3
2 1 4 3
1 2 3 4

This can be easily achieved with the itertools.permutations method:
import itertools
a = [1,2,3,4]
list(itertools.permutations(a))
[(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

Related

To generate a list, allowing duplicates and fitting a condition

From choices [1,2,3], I want to output all possible combinations, allowing duplicates in the choices, in a list of 5 elements.
In each of the lists, there must be at least one of 1, at least one of 2, and at least one of 3.
A clumsy way as below. It firstly generates a list of 5 using either in [1,2,3]. All generated lists are examined to have at least each of [1,2,3]. The qualified ones are put into a big list. Then the duplicates in the big list are removed (loop it many times to make sure good coverage):
import random
import itertools
choices = [1,2,3]
big_list = []
for a in range(10000):
new_list = [random.choice(choices) for i in range(5)]
if new_list.count(1) >= 1 and new_list.count(2) >= 1 and new_list.count(3) >= 1:
big_list.append(new_list)
big_list.sort()
final_list = list(big_list for big_list, _ in itertools.groupby(big_list))
# this line to remove the duplicates in the list of lists
print (final_list)
Considering the sequence matters, that is, [1,1,1,2,3] and [2,3,1,1,1] are two different lists.
What would be the smarter and more comprehensive way to do so?
Maybe you could could use itertools.combinations_with_replacement, itertools.permutations along with collections.Counter:
>>> from collections import Counter
>>> from itertools import combinations_with_replacement, permutations
>>>
>>> def is_valid_combination(comb: tuple) -> bool:
... digit_counts = Counter(comb)
... return digit_counts[1] >= 1 and \
... digit_counts[2] >= 1 and \
... digit_counts[3] >= 1
...
>>> choices = [1, 2, 3]
>>> valid_combinations = [
... c for c in combinations_with_replacement(choices, r=5)
... if is_valid_combination(c)
... ]
>>>
>>> valid_combinations
[(1, 1, 1, 2, 3), (1, 1, 2, 2, 3), (1, 1, 2, 3, 3), (1, 2, 2, 2, 3), (1, 2, 2, 3, 3), (1, 2, 3, 3, 3)]
>>>
>>> all_permutations_of_valid_combinations = {
... p
... for c in valid_combinations for p in permutations(c)
... }
>>>
>>> all_permutations_of_valid_combinations
{(2, 1, 3, 1, 2), (2, 1, 3, 2, 1), (3, 3, 2, 1, 3), (1, 2, 3, 2, 3), (1, 2, 1, 3, 1), (3, 1, 2, 3, 2), (3, 3, 3, 2, 1), (3, 2, 2, 1, 1), (1, 2, 2, 3, 1), (1, 3, 2, 2, 3), (1, 3, 2, 3, 2), (1, 2, 1, 1, 3), (3, 1, 3, 3, 2), (3, 1, 1, 2, 3), (2, 1, 3, 2, 3), (1, 2, 2, 1, 3), (1, 2, 1, 3, 3), (2, 3, 3, 1, 2), (2, 3, 3, 2, 1), (3, 3, 1, 2, 1), (3, 2, 3, 2, 1), (1, 2, 2, 3, 3), (3, 2, 1, 1, 1), (2, 2, 1, 3, 1), (2, 3, 1, 1, 1), (1, 3, 1, 2, 3), (3, 3, 1, 1, 2), (3, 2, 3, 1, 2), (2, 1, 2, 3, 1), (2, 2, 1, 1, 3), (3, 2, 1, 3, 1), (2, 3, 1, 3, 1), (1, 1, 3, 2, 1), (2, 3, 2, 1, 2), (2, 3, 2, 2, 1), (2, 1, 2, 1, 3), (3, 2, 1, 1, 3), (2, 2, 1, 3, 3), (2, 3, 1, 1, 3), (2, 3, 1, 2, 2), (3, 2, 3, 3, 1), (1, 1, 3, 1, 2), (2, 1, 2, 3, 3), (3, 3, 2, 2, 1), (3, 1, 2, 1, 2), (3, 2, 1, 3, 3), (3, 1, 2, 2, 1), (2, 3, 1, 3, 3), (1, 1, 3, 2, 3), (3, 3, 3, 1, 2), (1, 2, 3, 1, 1), (1, 1, 3, 3, 2), (3, 1, 3, 1, 2), (2, 3, 2, 3, 1), (1, 3, 2, 1, 1), (2, 1, 3, 3, 1), (3, 2, 2, 3, 1), (3, 1, 2, 2, 3), (1, 3, 2, 2, 2), (1, 2, 3, 1, 3), (1, 3, 2, 3, 1), (3, 2, 2, 1, 3), (2, 2, 3, 2, 1), (3, 1, 1, 2, 2), (1, 1, 2, 2, 3), (2, 1, 3, 2, 2), (1, 3, 3, 2, 2), (3, 3, 1, 3, 2), (2, 1, 1, 3, 1), (1, 3, 2, 1, 3), (2, 1, 3, 3, 3), (3, 1, 3, 2, 2), (2, 2, 3, 1, 2), (1, 1, 2, 3, 1), (3, 2, 1, 2, 2), (1, 2, 2, 3, 2), (3, 3, 1, 2, 3), (1, 3, 2, 3, 3), (1, 2, 1, 2, 3), (3, 2, 3, 1, 1), (1, 3, 1, 2, 2), (1, 2, 2, 2, 3), (2, 1, 1, 3, 3), (3, 1, 1, 3, 2), (1, 1, 2, 3, 3), (1, 3, 3, 3, 2), (2, 3, 2, 1, 1), (2, 2, 1, 2, 3), (2, 2, 1, 3, 2), (1, 2, 3, 3, 1), (3, 2, 3, 1, 3), (2, 3, 1, 2, 1), (2, 1, 3, 1, 1), (3, 3, 2, 1, 2), (1, 2, 3, 2, 2), (1, 3, 1, 3, 2), (3, 1, 2, 3, 1), (2, 2, 2, 3, 1), (2, 1, 2, 2, 3), (1, 2, 3, 3, 3), (2, 3, 1, 2, 3), (2, 1, 3, 1, 3), (3, 2, 2, 2, 1), (1, 2, 1, 3, 2), (2, 3, 3, 1, 1), (3, 1, 2, 3, 3), (3, 2, 2, 1, 2), (3, 1, 1, 2, 1), (1, 3, 3, 2, 1), (2, 3, 3, 3, 1), (2, 1, 1, 1, 3), (1, 3, 2, 1, 2), (2, 1, 3, 3, 2), (1, 1, 1, 2, 3), (3, 1, 3, 2, 1), (1, 1, 1, 3, 2), (2, 2, 3, 1, 1), (3, 1, 1, 1, 2), (1, 1, 2, 1, 3), (1, 3, 3, 1, 2), (3, 2, 1, 2, 1), (2, 3, 3, 1, 3), (3, 3, 1, 2, 2), (2, 2, 3, 3, 1), (1, 3, 1, 2, 1), (1, 3, 3, 2, 3), (3, 2, 1, 1, 2), (2, 1, 1, 3, 2), (2, 3, 1, 1, 2), (3, 1, 3, 2, 3), (2, 2, 3, 1, 3), (1, 3, 1, 1, 2), (1, 1, 2, 3, 2), (2, 1, 2, 3, 2), (3, 2, 1, 2, 3), (3, 1, 2, 1, 1), (3, 2, 1, 3, 2), (2, 1, 1, 2, 3), (2, 3, 1, 3, 2), (1, 1, 3, 2, 2), (2, 3, 2, 1, 3), (3, 3, 2, 3, 1), (3, 3, 2, 1, 1), (1, 2, 3, 2, 1), (3, 1, 2, 1, 3), (2, 2, 2, 1, 3), (3, 1, 2, 2, 2), (1, 3, 2, 2, 1), (1, 2, 3, 1, 2), (1, 2, 3, 3, 2)}
Apart from the itertools.combinations itself, you could use some recursive logic:
def combinations(choices, n = 5):
if n == 1:
return [[x,] for x in choices]
else:
return [v + [x,] for v in combinations(choices, n = n -1) for x in choices]
To select only the combinations which contain at least one 1, 2 and 3:
[x for x in combinations(choices, n = 5) if all(c in x for c in choices)]

Permutations Function Issue

I've been struggling with defining a function that returns the permutations of a given array.
I have written the code below:
def gPermutations(array):
result = []
idx = 0
for element in array:
for i in range(len(array)):
if i != idx:
z = array[:array.index(element)]
z.append(array[i])
s = z[:] + array[array.index(element)+1:]
s[i] = element
result.append(s)
idx += 1
return result
This code seems to work by returning some of the permutations of an array, but doesn't return all of them, and sometimes duplicates a certain permutation. May someone please explain what is the issue with my code? Thanks!
Use the permutations method from itertools
In [1]: from itertools import permutations
In [2]: arr = [1,2,3,4]
In [3]: for perm in permutations(arr, len(arr)):
...: print(perm)
...:
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)
If you truly want all the permutations (re-orderings?) of your list, I'd use the itertools package:
>>> from itertools import permutations
>>> array = [1, 2, 3]
>>> print(list(permutations(array)))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

How to increment i in the loop for using python to select different column

I would like to know how could be possible to create a loop for in Python 3 to increment the values of i, j, k ... for a specific application.
I need to select different columns but they cannot be select with themselves. Let's suppose that my dataframe has 7 columns. I will put an example bellow.
The idea is to create a selection like that:
[0, 1]
[0, 2]
[0, 3]
[0, 4]
[0, 5]
[0, 6]
...
[0, 3, 6]
[0, 3, 7]
[0, 4, 5]
[0, 4, 6]
[0, 4, 7]
[0, 5, 6]
[0, 5, 7]
[0, 6, 7]
[0, 1, 2, 3]
[0, 1, 2, 4]
[0, 1, 2, 5]
[0, 1, 2, 6]
[0, 1, 2, 7]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 5]
[0, 1, 2, 3, 6]
[0, 1, 2, 3, 7]
...
[0, 1, 2, 3, 4, 7]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 7]
[0, 1, 2, 3, 4, 5, 8]
[0, 1, 2, 3, 4, 5, 6, 7]
After some replies, I could be able to create the following code:
from itertools import combinations
numbers = []
A = [0,1,2,3,4,5,6,7]
for i in range(8):
for combo in combinations(A, i+2):
numbrs.append(combo)
The output is:
[(0, 1),
(0, 2),
(0, 3),
(0, 4), ...
How could I use those numbers as index of a iloc iterator ?
For examples, the numbers generated must substitute the code:
df.iloc[:,[i, j, k, ...]]
Then I will be able to interact among the columns
You can solve this using itertools.combinations and itertools.chain:
import itertools as it
list(it.chain(*(it.combinations(range(8), r) for r in range(2, 9))))
Or using a list comprehension if you prefer:
[x for r in range(2, 9) for x in it.combinations(range(8), r)]
This produces the following output:
[(0, 1),
(0, 2),
(0, 3),
(0, 4),
(0, 5),
(0, 6),
(0, 7),
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(1, 6),
(1, 7),
(2, 3),
(2, 4),
(2, 5),
(2, 6),
(2, 7),
(3, 4),
(3, 5),
(3, 6),
(3, 7),
(4, 5),
(4, 6),
(4, 7),
(5, 6),
(5, 7),
(6, 7),
(0, 1, 2),
(0, 1, 3),
(0, 1, 4),
(0, 1, 5),
(0, 1, 6),
(0, 1, 7),
(0, 2, 3),
(0, 2, 4),
(0, 2, 5),
(0, 2, 6),
(0, 2, 7),
(0, 3, 4),
(0, 3, 5),
(0, 3, 6),
(0, 3, 7),
(0, 4, 5),
(0, 4, 6),
(0, 4, 7),
(0, 5, 6),
(0, 5, 7),
(0, 6, 7),
(1, 2, 3),
(1, 2, 4),
(1, 2, 5),
(1, 2, 6),
(1, 2, 7),
(1, 3, 4),
(1, 3, 5),
(1, 3, 6),
(1, 3, 7),
(1, 4, 5),
(1, 4, 6),
(1, 4, 7),
(1, 5, 6),
(1, 5, 7),
(1, 6, 7),
(2, 3, 4),
(2, 3, 5),
(2, 3, 6),
(2, 3, 7),
(2, 4, 5),
(2, 4, 6),
(2, 4, 7),
(2, 5, 6),
(2, 5, 7),
(2, 6, 7),
(3, 4, 5),
(3, 4, 6),
(3, 4, 7),
(3, 5, 6),
(3, 5, 7),
(3, 6, 7),
(4, 5, 6),
(4, 5, 7),
(4, 6, 7),
(5, 6, 7),
(0, 1, 2, 3),
(0, 1, 2, 4),
(0, 1, 2, 5),
(0, 1, 2, 6),
(0, 1, 2, 7),
(0, 1, 3, 4),
(0, 1, 3, 5),
(0, 1, 3, 6),
(0, 1, 3, 7),
(0, 1, 4, 5),
(0, 1, 4, 6),
(0, 1, 4, 7),
(0, 1, 5, 6),
(0, 1, 5, 7),
(0, 1, 6, 7),
(0, 2, 3, 4),
(0, 2, 3, 5),
(0, 2, 3, 6),
(0, 2, 3, 7),
(0, 2, 4, 5),
(0, 2, 4, 6),
(0, 2, 4, 7),
(0, 2, 5, 6),
(0, 2, 5, 7),
(0, 2, 6, 7),
(0, 3, 4, 5),
(0, 3, 4, 6),
(0, 3, 4, 7),
(0, 3, 5, 6),
(0, 3, 5, 7),
(0, 3, 6, 7),
(0, 4, 5, 6),
(0, 4, 5, 7),
(0, 4, 6, 7),
(0, 5, 6, 7),
(1, 2, 3, 4),
(1, 2, 3, 5),
(1, 2, 3, 6),
(1, 2, 3, 7),
(1, 2, 4, 5),
(1, 2, 4, 6),
(1, 2, 4, 7),
(1, 2, 5, 6),
(1, 2, 5, 7),
(1, 2, 6, 7),
(1, 3, 4, 5),
(1, 3, 4, 6),
(1, 3, 4, 7),
(1, 3, 5, 6),
(1, 3, 5, 7),
(1, 3, 6, 7),
(1, 4, 5, 6),
(1, 4, 5, 7),
(1, 4, 6, 7),
(1, 5, 6, 7),
(2, 3, 4, 5),
(2, 3, 4, 6),
(2, 3, 4, 7),
(2, 3, 5, 6),
(2, 3, 5, 7),
(2, 3, 6, 7),
(2, 4, 5, 6),
(2, 4, 5, 7),
(2, 4, 6, 7),
(2, 5, 6, 7),
(3, 4, 5, 6),
(3, 4, 5, 7),
(3, 4, 6, 7),
(3, 5, 6, 7),
(4, 5, 6, 7),
(0, 1, 2, 3, 4),
(0, 1, 2, 3, 5),
(0, 1, 2, 3, 6),
(0, 1, 2, 3, 7),
(0, 1, 2, 4, 5),
(0, 1, 2, 4, 6),
(0, 1, 2, 4, 7),
(0, 1, 2, 5, 6),
(0, 1, 2, 5, 7),
(0, 1, 2, 6, 7),
(0, 1, 3, 4, 5),
(0, 1, 3, 4, 6),
(0, 1, 3, 4, 7),
(0, 1, 3, 5, 6),
(0, 1, 3, 5, 7),
(0, 1, 3, 6, 7),
(0, 1, 4, 5, 6),
(0, 1, 4, 5, 7),
(0, 1, 4, 6, 7),
(0, 1, 5, 6, 7),
(0, 2, 3, 4, 5),
(0, 2, 3, 4, 6),
(0, 2, 3, 4, 7),
(0, 2, 3, 5, 6),
(0, 2, 3, 5, 7),
(0, 2, 3, 6, 7),
(0, 2, 4, 5, 6),
(0, 2, 4, 5, 7),
(0, 2, 4, 6, 7),
(0, 2, 5, 6, 7),
(0, 3, 4, 5, 6),
(0, 3, 4, 5, 7),
(0, 3, 4, 6, 7),
(0, 3, 5, 6, 7),
(0, 4, 5, 6, 7),
(1, 2, 3, 4, 5),
(1, 2, 3, 4, 6),
(1, 2, 3, 4, 7),
(1, 2, 3, 5, 6),
(1, 2, 3, 5, 7),
(1, 2, 3, 6, 7),
(1, 2, 4, 5, 6),
(1, 2, 4, 5, 7),
(1, 2, 4, 6, 7),
(1, 2, 5, 6, 7),
(1, 3, 4, 5, 6),
(1, 3, 4, 5, 7),
(1, 3, 4, 6, 7),
(1, 3, 5, 6, 7),
(1, 4, 5, 6, 7),
(2, 3, 4, 5, 6),
(2, 3, 4, 5, 7),
(2, 3, 4, 6, 7),
(2, 3, 5, 6, 7),
(2, 4, 5, 6, 7),
(3, 4, 5, 6, 7),
(0, 1, 2, 3, 4, 5),
(0, 1, 2, 3, 4, 6),
(0, 1, 2, 3, 4, 7),
(0, 1, 2, 3, 5, 6),
(0, 1, 2, 3, 5, 7),
(0, 1, 2, 3, 6, 7),
(0, 1, 2, 4, 5, 6),
(0, 1, 2, 4, 5, 7),
(0, 1, 2, 4, 6, 7),
(0, 1, 2, 5, 6, 7),
(0, 1, 3, 4, 5, 6),
(0, 1, 3, 4, 5, 7),
(0, 1, 3, 4, 6, 7),
(0, 1, 3, 5, 6, 7),
(0, 1, 4, 5, 6, 7),
(0, 2, 3, 4, 5, 6),
(0, 2, 3, 4, 5, 7),
(0, 2, 3, 4, 6, 7),
(0, 2, 3, 5, 6, 7),
(0, 2, 4, 5, 6, 7),
(0, 3, 4, 5, 6, 7),
(1, 2, 3, 4, 5, 6),
(1, 2, 3, 4, 5, 7),
(1, 2, 3, 4, 6, 7),
(1, 2, 3, 5, 6, 7),
(1, 2, 4, 5, 6, 7),
(1, 3, 4, 5, 6, 7),
(2, 3, 4, 5, 6, 7),
(0, 1, 2, 3, 4, 5, 6),
(0, 1, 2, 3, 4, 5, 7),
(0, 1, 2, 3, 4, 6, 7),
(0, 1, 2, 3, 5, 6, 7),
(0, 1, 2, 4, 5, 6, 7),
(0, 1, 3, 4, 5, 6, 7),
(0, 2, 3, 4, 5, 6, 7),
(1, 2, 3, 4, 5, 6, 7),
(0, 1, 2, 3, 4, 5, 6, 7)]

Get all combination of list with repeated values

How can i get a list of all possible values of a list with also repeated ones?
I've tried itertools.combination_with_replacement and itertools.permutation but the first exclude the inverted order (such as [3, 2, 1]) and the second exclude multiple values (such as [3, 3, 1]).
I need something like this:
Example:
list = [1, 2, 3]
results =
[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
...
[3, 1, 1]
[3, 1, 2]
[3, 1, 3]
...
What can I do in Python to achieve this?
Thanks in advance.
You're looking for itertools.product, setting the repetition to 3:
>>> from itertools import product
>>> lst = [1, 2, 3]
>>> list(product(lst, repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 3, 1), (1, 3, 2), (1, 3, 3), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 3, 1), (2, 3, 2), (2, 3, 3), (3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 3, 1), (3, 3, 2), (3, 3, 3)]

How to use itertools to output results of only a certain length

Suppose I have a list of bytes (x00 to xFF). How can I use itertools to return only permutations that have length of X.
So for example I want all permutations with length 3, then I'll get
[x00,x00,x00], [x00,x00,x01], ..., [xFF,xFF,xFF]
That way there is no waste of computing resources.
EDIT: Doesn't have to be itertools if there is a better way.
import itertools
for tup in itertools.product(range(0x100), repeat=3):
...
It seems #gnibbler's solution is more correct?
In [162]: >>> l = [1, 2, 3]
In [163]: list(itertools.combinations_with_replacement(l, 3))
Out[163]:
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 2, 2),
(1, 2, 3),
(1, 3, 3),
(2, 2, 2),
(2, 2, 3),
(2, 3, 3),
(3, 3, 3)]
In [164]: list(itertools.product(l, repeat=3))
Out[164]:
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 2, 1),
(1, 2, 2),
(1, 2, 3),
(1, 3, 1),
(1, 3, 2),
(1, 3, 3),
(2, 1, 1),
(2, 1, 2),
(2, 1, 3),
(2, 2, 1),
(2, 2, 2),
(2, 2, 3),
(2, 3, 1),
(2, 3, 2),
(2, 3, 3),
(3, 1, 1),
(3, 1, 2),
(3, 1, 3),
(3, 2, 1),
(3, 2, 2),
(3, 2, 3),
(3, 3, 1),
(3, 3, 2),
(3, 3, 3)]
itertools.combinations_with_replacement:
>>> my_list = [1, 2, 3, 4]
>>> import itertools
>>>
>>> list(itertools.combinations_with_replacement(my_list, 3))
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4),
(1, 2, 2), (1, 2, 3), (1, 2, 4),
(1, 3, 3), (1, 3, 4),
(1, 4, 4),
(2, 2, 2), (2, 2, 3), (2, 2, 4),
(2, 3, 3), (2, 3, 4),
(2, 4, 4),
(3, 3, 3), (3, 3, 4),
(3, 4, 4),
(4, 4, 4)]
Seems like you want all the permutations, with replacement. In that case, you need: itertools.product as in #gnibbler's answer.

Categories

Resources