【问题标题】:Calculating all combinations of nested lists based on logical expression基于逻辑表达式计算嵌套列表的所有组合
【发布时间】:2016-11-29 22:32:15
【问题描述】:

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

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

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

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

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']

问题:

  • 使用元组和列表的合取和析取表示的想法是一个好主意吗?
  • 什么是实现此功能的有效方法?
  • 是否有可能实现该功能,计算 所有组合,与 itertools? (我不是很熟悉 它们,但我听说它们非常强大)

感谢您的帮助。

【问题讨论】:

    标签: python nested logical-operators itertools


    【解决方案1】:

    遗憾的是,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']) 的(递归生成的)组合结合起来。

    这也消除了用列表和元组表示合取和析取的需要,老实说,我觉得这很混乱。

    【讨论】:

    • 太好了,谢谢。作为扩展,我还考虑接受列表元素,其中包含提到的字符串作为第一个元素,例如[['a1', {'param': 'something'}], ['b2', {'param': 'something'}]。应该传递第二个元素(字典)。
    【解决方案2】:

    Python 中还有一个 set type 支持集合操作 - 如果您不关心排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      相关资源
      最近更新 更多