假设我有一个动作列表,其中可以包含三种不同类型的动作:

类型A:可以包含所有类型的操作(分离)
B型:可以包含所有类型的动作(有序连词)
类型C:不能包含子操作。这是我最后要达到的水平。

我考虑过(基于:python - representing boolean expressions with lists),可以用元组或列表分别表示析取和合取,但是我不确定这是否是最佳解决方案。

对于A和B类型,有一个dict,其中包含type元素,例如

type_a = {
‘a1’: ('b1', 'a2'),
‘a2’: ('c1', 'c2')
}

type_b = {
‘b1’: ['c4', 'c5', 'c7'],
‘b2’:['c3', 'c4']
}


详细说明:

“ a1”等于('b1', 'a2'),等于(['c4', 'c5','c7'], 'c1', 'c2')

“ a2”等于('c1', 'c2')

“ b1”等于['c4', 'c5', 'c7']

“ b2”等于['c3', 'c4']

输入示例:

['a1', 'b2', 'c6']


预期产量:

结果应仅包含C型操作。

生的

[(['c4', 'c5', 'c7'], 'c1', 'c2'), 'c3', 'c4', 'c6']


所有组合

['c4', 'c5','c7', 'c3', 'c4', 'c6']

['c1', 'c3', 'c4', 'c6']

['c2', 'c3', 'c4', 'c6']


问题:


具有tuple和list的合取表示的想法是好主意吗?
什么是实现此目的的有效方法?
是否有可能实现该功能,
所有组合,以及itertools? (我不是很熟悉
它们,但我听说它们非常强大)


谢谢你的帮助。

最佳答案

可悲的是,itertools在这里并没有太大帮助。下面的递归野兽似乎可以完成任务:

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


这个想法是为第一个动作('a1')生成所有可能的值,并将它们与其余动作(['b2', 'c6'])的(递归生成的)组合相结合。

这也消除了用列表和元组表示合取和析取的需要,老实说,我发现这很令人困惑。

10-07 12:34
查看更多