I want to create a table that one column is choosing 3 out of a list [1,2,3,4] randomly with replacement. Then another column is only changing the middle number.
For example,
column 1 column2
111 121
111 131
111 141
121 111
121 131
...
444 414
444 424
444 434
The total should be 64 combinations. I tried combinations_with_replacement()
lst = [1,2,3,4]
ref = list(it.combinations_with_replacement(lst, 3))
>>> print(ref)
[(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)]
>>> len(ref)
20
but it did not work as I wanted... Any suggestions on how to change?
Thanks
Just as a hint:
col1 = []
col2 = []
for i in range(4):
for j in range(4):
for k in range(4):
col1.append([i + 1, j + 1, k + 1])
for l in range(3):
col2.append([i + 1, (j + l + 1) % 4 + 1, k + 1])
print ("The list\n" + str(col1) + "\nhas " + str(len(col1)) + " entries")
print ("The list\n" + str(col2) + "\nhas " + str(len(col2)) + " entries")
This yields:
The list
[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]
has 64 entries
The list
[[1, 2, 1], [1, 3, 1], [1, 4, 1], [1, 2, 2], [1, 3, 2], [1, 4, 2], [1, 2, 3], [1, 3, 3], [1, 4, 3], [1, 2, 4], [1, 3, 4], [1, 4, 4], [1, 3, 1], [1, 4, 1], [1, 1, 1], [1, 3, 2], [1, 4, 2], [1, 1, 2], [1, 3, 3], [1, 4, 3], [1, 1, 3], [1, 3, 4], [1, 4, 4], [1, 1, 4], [1, 4, 1], [1, 1, 1], [1, 2, 1], [1, 4, 2], [1, 1, 2], [1, 2, 2], [1, 4, 3], [1, 1, 3], [1, 2, 3], [1, 4, 4], [1, 1, 4], [1, 2, 4], [1, 1, 1], [1, 2, 1], [1, 3, 1], [1, 1, 2], [1, 2, 2], [1, 3, 2], [1, 1, 3], [1, 2, 3], [1, 3, 3], [1, 1, 4], [1, 2, 4], [1, 3, 4], [2, 2, 1], [2, 3, 1], [2, 4, 1], [2, 2, 2], [2, 3, 2], [2, 4, 2], [2, 2, 3], [2, 3, 3], [2, 4, 3], [2, 2, 4], [2, 3, 4], [2, 4, 4], [2, 3, 1], [2, 4, 1], [2, 1, 1], [2, 3, 2], [2, 4, 2], [2, 1, 2], [2, 3, 3], [2, 4, 3], [2, 1, 3], [2, 3, 4], [2, 4, 4], [2, 1, 4], [2, 4, 1], [2, 1, 1], [2, 2, 1], [2, 4, 2], [2, 1, 2], [2, 2, 2], [2, 4, 3], [2, 1, 3], [2, 2, 3], [2, 4, 4], [2, 1, 4], [2, 2, 4], [2, 1, 1], [2, 2, 1], [2, 3, 1], [2, 1, 2], [2, 2, 2], [2, 3, 2], [2, 1, 3], [2, 2, 3], [2, 3, 3], [2, 1, 4], [2, 2, 4], [2, 3, 4], [3, 2, 1], [3, 3, 1], [3, 4, 1], [3, 2, 2], [3, 3, 2], [3, 4, 2], [3, 2, 3], [3, 3, 3], [3, 4, 3], [3, 2, 4], [3, 3, 4], [3, 4, 4], [3, 3, 1], [3, 4, 1], [3, 1, 1], [3, 3, 2], [3, 4, 2], [3, 1, 2], [3, 3, 3], [3, 4, 3], [3, 1, 3], [3, 3, 4], [3, 4, 4], [3, 1, 4], [3, 4, 1], [3, 1, 1], [3, 2, 1], [3, 4, 2], [3, 1, 2], [3, 2, 2], [3, 4, 3], [3, 1, 3], [3, 2, 3], [3, 4, 4], [3, 1, 4], [3, 2, 4], [3, 1, 1], [3, 2, 1], [3, 3, 1], [3, 1, 2], [3, 2, 2], [3, 3, 2], [3, 1, 3], [3, 2, 3], [3, 3, 3], [3, 1, 4], [3, 2, 4], [3, 3, 4], [4, 2, 1], [4, 3, 1], [4, 4, 1], [4, 2, 2], [4, 3, 2], [4, 4, 2], [4, 2, 3], [4, 3, 3], [4, 4, 3], [4, 2, 4], [4, 3, 4], [4, 4, 4], [4, 3, 1], [4, 4, 1], [4, 1, 1], [4, 3, 2], [4, 4, 2], [4, 1, 2], [4, 3, 3], [4, 4, 3], [4, 1, 3], [4, 3, 4], [4, 4, 4], [4, 1, 4], [4, 4, 1], [4, 1, 1], [4, 2, 1], [4, 4, 2], [4, 1, 2], [4, 2, 2], [4, 4, 3], [4, 1, 3], [4, 2, 3], [4, 4, 4], [4, 1, 4], [4, 2, 4], [4, 1, 1], [4, 2, 1], [4, 3, 1], [4, 1, 2], [4, 2, 2], [4, 3, 2], [4, 1, 3], [4, 2, 3], [4, 3, 3], [4, 1, 4], [4, 2, 4], [4, 3, 4]]
has 192 entries
itertools.combinations_with_replacement will sort the results and remove duplicates. (1,2,1) will be sorted to (1,1,2) and removed because (1,1,2) already exists. What you are looking for is itertools.product.
lst = [1,2,3,4]
ref = list(it.product(lst, repeat=3))
>>> len(ref)
64
How to create a list with n-size non-repeating sublists from given list?
I think the example will explain a lot.
given_list = [1, 2, 3, 4, 5]
n = 3
desired_list = [[1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,3,5], [1,4,5], [2,3,4], [2,3,5], [2,4,5], [3,4,5]]
EDIT:
I forgot to add some important combinations
Not sure if you want combinations or permutations, so here are both:
Permutations
You can use permutations from itertools to find all permutations of a given list:
from itertools import permutations
given_list = [1, 2, 3, 4, 5]
n = 3
print([list(i) for i in permutations(given_list, n)])
Output:
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 2], [1, 3, 4], [1, 3, 5], [1, 4, 2], [1
, 4, 3], [1, 4, 5], [1, 5, 2], [1, 5, 3], [1, 5, 4], [2, 1, 3], [2, 1, 4], [2, 1
, 5], [2, 3, 1], [2, 3, 4], [2, 3, 5], [2, 4, 1], [2, 4, 3], [2, 4, 5], [2, 5, 1
], [2, 5, 3], [2, 5, 4], [3, 1, 2], [3, 1, 4], [3, 1, 5], [3, 2, 1], [3, 2, 4],
[3, 2, 5], [3, 4, 1], [3, 4, 2], [3, 4, 5], [3, 5, 1], [3, 5, 2], [3, 5, 4], [4,
1, 2], [4, 1, 3], [4, 1, 5], [4, 2, 1], [4, 2, 3], [4, 2, 5], [4, 3, 1], [4, 3,
2], [4, 3, 5], [4, 5, 1], [4, 5, 2], [4, 5, 3], [5, 1, 2], [5, 1, 3], [5, 1, 4]
, [5, 2, 1], [5, 2, 3], [5, 2, 4], [5, 3, 1], [5, 3, 2], [5, 3, 4], [5, 4, 1], [
5, 4, 2], [5, 4, 3]]
Combinations
And you can use combinations from itertools to find all the combinations of a given list:
from itertools import combinations
given_list = [1, 2, 3, 4, 5]
n = 3
print([list(i) for i in combinations(given_list, n)])
Output:
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2
, 3, 5], [2, 4, 5], [3, 4, 5]]
A fast implementation of permutations:
sub perm {
my ($init,$k) = #_;
my $n=length($init); my $dn=$n;
my $out=""; my $m=$k;
for (my $i=0;$i<$n;$i++) {
my $ind=$m % $dn;
$out.=substr($init,$ind,1);
$m=$m / $dn;
$dn--;
substr($init,$ind,1,substr($init,$dn,1));
}
return $out
}
k = 0 .. length(init)-1; each k giving an unique permutation, seemly randomly.
to calculate the factorial length(init)!
sub fac {
my ($f) = #_;
my $fac=1; while ($f>1) { $fac*=$f; $f-- } return $fac
}
I have a very straightforward combination problem. I have two arrays (a and b). Array a indicates all the values one of the three slots in array b can take on. Each slot in array b can have a value between 1 and 5. An example of which would be [1, 4, 5]. I would like to generate an array (c) with all possible combinations. I like to extend the basic example larger arrays.
Input:
a = [1, 2, 3, 4, 5]
b = [1, 2, 3]
Output:
c = [[1, 1, 1], [1, 1, 2],[1, 1, 3], [1, 1, 4], [1, 1, 5],
[1, 2, 1], [1, 2, 2],[1, 2, 3], [1, 2, 4], [1, 2, 5],
[1, 3, 1], [1, 3, 2],[1, 3, 3], [1, 3, 4], [1, 3, 5],
[1, 4, 1], [1, 4, 2],[1, 4, 3], [1, 4, 4], [1, 4, 5],
[1, 5, 1], [1, 5, 2],[1, 5, 3], [1, 5, 4], [1, 5, 5],
[2, 1, 1], [2, 1, 2],[2, 1, 3], [2, 1, 4], [2, 1, 5],
[2, 2, 1], [2, 2, 2],[2, 2, 3], [2, 2, 4], [2, 2, 5],
[2, 3, 1], [2, 3, 2],[2, 3, 3], [2, 3, 4], [2, 3, 5],
[2, 4, 1], [2, 4, 2],[2, 4, 3], [2, 4, 4], [2, 4, 5],
[2, 5, 1], [2, 5, 2],[2, 5, 3], [2, 5, 4], [2, 5, 5],
[3, 1, 1], [3, 1, 2],[3, 1, 3], [3, 1, 4], [3, 1, 5],
[3, 2, 1], [3, 2, 2],[3, 2, 3], [3, 2, 4], [3, 2, 5],
[3, 3, 1], [3, 3, 2],[3, 3, 3], [3, 3, 4], [3, 3, 5],
[3, 4, 1], [3, 4, 2],[3, 4, 3], [3, 4, 4], [3, 4, 5],
[3, 5, 1], [3, 5, 2],[3, 5, 3], [3, 5, 4], [3, 5, 5],
[4, 1, 1], [4, 1, 2],[4, 1, 3], [4, 1, 4], [4, 1, 5],
[4, 2, 1], [4, 2, 2],[4, 2, 3], [4, 2, 4], [4, 2, 5],
[4, 3, 1], [4, 3, 2],[4, 3, 3], [4, 3, 4], [4, 3, 5],
[4, 4, 1], [4, 4, 2],[4, 4, 3], [4, 4, 4], [4, 4, 5],
[5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5],
[5, 1, 1], [5, 1, 2],[5, 1, 3], [5, 1, 4], [5, 1, 5],
[5, 2, 1], [5, 2, 2],[5, 2, 3], [5, 2, 4], [5, 2, 5],
[5, 3, 1], [5, 3, 2],[5, 3, 3], [5, 3, 4], [5, 3, 5],
[5, 4, 1], [5, 4, 2],[5, 4, 3], [5, 4, 4], [5, 4, 5],
[5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5]]
Solution for the problem above:
d = []
for i in range(len(a)):
for j in range(len(a)):
for k in range(len(a)):
e = []
e.append(i+1)
e.append(j+1)
e.append(k+1)
d.append(e)
I am looking for a more generic way. One which can accommodate larger arrays (see below) without the need to use a nested for loop structure. I searched for a comparable example, but was unable to find one on stackoverflow.
Input:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
You are looking for itertools.product().
a = [1, 2, 3, 4, 5]
b = 3 # Actually, you just need the length of the array, values do not matter
c = itertools.product(a, repeat=b)
Note that this returns an iterator, you may need to cast it using list() but be aware this can take forever and highly consume memory if the sizes grow.
In the general case, you should of course use the itertools module, in this particular case itertools.product, as explained in the other answer.
If you want to implement the function yourself, you can use recursion to make it applicable to any array sizes. Also, you should probably make it a generator function (using yield instead of return), as the result could be rather long. You can try something like this:
def combinations(lst, num):
if num > 0:
for x in lst:
for comb in combinations(lst, num - 1):
yield [x] + comb
else:
yield []