Reputation: 362
Let's assume I have a action list, which can contain three different type of actions:
Type A: can contain all types of actions (disjunction)
Type B: can contain all types of actions (ordered conjunction)
Type C: cannot contain subactions. This is the level I want to have at the end.
I thought about (based on: python - representing boolean expressions with lists) that the disjunction and conjunction could be represented by a tuple respectively a list, but I am not sure whether this is an optimal solution.
For type A and B, there is a dict which contains the type elements, e.g.
type_a = {
‘a1’: ('b1', 'a2'),
‘a2’: ('c1', 'c2')
}
type_b = {
‘b1’: ['c4', 'c5', 'c7'],
‘b2’:['c3', 'c4']
}
Detailed explanation:
‘a1’ is equal to ('b1', 'a2')
, which is equal to (['c4', 'c5','c7'], 'c1', 'c2')
‘a2’ is equal to ('c1', 'c2')
‘b1’ is equal to ['c4', 'c5', 'c7']
‘b2’ is equal to ['c3', 'c4']
Example Input:
['a1', 'b2', 'c6']
Expected output:
The results should only contain type C actions.
raw
[(['c4', 'c5', 'c7'], 'c1', 'c2'), 'c3', 'c4', 'c6']
all combinations
['c4', 'c5','c7', 'c3', 'c4', 'c6']
['c1', 'c3', 'c4', 'c6']
['c2', 'c3', 'c4', 'c6']
Questions:
Thanks for any help.
Upvotes: 1
Views: 219
Reputation: 43146
Sadly, itertools isn't of much help here. The following recursive beast seems to do the job however:
def combinations(actions):
if len(actions)==1:
action= actions[0]
try:
actions= type_a[action]
except KeyError:
try:
actions= type_b[action]
except KeyError:
#action is of type C, the only possible combination is itself
yield actions
else:
#action is of type B (conjunction), combine all the actions
for combination in combinations(actions):
yield combination
else:
#action is of type A (disjunction), generate combinations for each action
for action in actions:
for combination in combinations([action]):
yield combination
else:
#generate combinations for the first action in the list
#and combine them with the combinations for the rest of the list
action= actions[0]
for combination in combinations(actions[1:]):
for combo in combinations([action]):
yield combo + combination
The idea is to generate all possible values for the first action ('a1'
) and combine them with the (recursively generated) combinations of the remaining actions (['b2', 'c6']
).
This also eliminates the need to represent conjunction and disjunction with lists and tuples, which, to be honest, I found rather confusing.
Upvotes: 1