So here is the issue.
First, here is normal itertools.product operation:
x = [[0, 1], [0, 1], [0, 1]]
itertools.product(*x)
The output is:
>>> [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
Now x
is an array of length 3. Let's say I define a "group plan":
# Note 0th and 1st group indices are both 0, indicating they are of the same group.
group plan = [0, 0, 1]
My goal is to implement a
def my_itertools_product_with_group(*args, group_plan=[0, 0, 1])
The correct solutions will be:
>>> [[0, 0, 0], [0, 0, 1], [1, 1, 0], [1, 1, 1]]
Because we can see for the 0th and 1st element of each list, they are the same, either [0, 0]
or [1, 1]
Another example:
arr = [['a0', 'A0'], ['a1', 'A1'], ['a2', 'A2'], ['a3', 'A3'], ['a4', 'A4'], ['a5', 'A5']]
The grouping scheme defined as [0, 0, 0, 1, 0, 2]
In that sense, still want to find all possible combinations
result = my_itertools_product_with_group(*arr, group_plan=[0, 0, 0, 1, 0, 2])
The legal outputs are:
result = [\
['a0', 'a1', 'a2', 'a3', 'a4', 'a5']
['a0', 'a1', 'a2', 'a3', 'a4', 'A5']
['a0', 'a1', 'a2', 'A3', 'a4', 'a5']
['a0', 'a1', 'a2', 'A3', 'a4', 'A5']
['A0', 'A1', 'A2', 'a3', 'A4', 'a5']
['A0', 'A1', 'A2', 'a3', 'A4', 'A5']
['A0', 'A1', 'A2', 'A3', 'A4', 'a5']
['A0', 'A1', 'A2', 'A3', 'A4', 'A5']]
My attempts:
I can do post filtering after calling normal itertool.product()
, but am also wondering if it is possible to do it in one-shot as defined by the def my_itertools_product_with_group(*args, group_plan)
Here is my post-filtering code where you can see, I first get cartesian product of [ [0, 1] * 5 ]
.
group_plan = [0, 0, 1, 2, 0] # meaning all elements marked as 0 should be treated as the same group
result = [x for x in itertools.product([0, 1], repeat=5) if grouped_as_planned(x, group_plan)]
...
def grouped_as_planned(arr, group_plan):
for x_ind, x in enumerate(arr):
for y_ind in range(x_ind + 1, len(arr)):
if group_plan[x_ind] == group_plan[y_ind]:
if x != arr[y_ind]:
return False
return True