列表的优先顺序组合

时间:2018-11-30 22:18:11

标签: python list combinations

首先,应生成列表的所有可能组合。这是直接的问题-感谢 itertools.combinations 。然后,必须根据以下优先级对组合进行排序:原始列表的第一个元素具有最高优先级,第二个元素具有第二优先级,依此类推。请注意,任何较低优先级的分组都不能高于任何较高优先级。 简单的例子:

input = ['A', 'B']
output = [['A', 'B'], ['A'], ['B']]

3个元素示例:

input = ['A', 'B', 'C']
output = [['A', 'B', 'C'], ['A', 'B'], ['A', 'C'], ['A'], ['B', 'C'], ['B'], ['C']]

问题:给定任何元素的列表,如何找到按上述优先级排序的所有可能组合的列表?

3 个答案:

答案 0 :(得分:3)

将元素添加到列表中总是会增加优先级。我们可以维护一个列表列表,然后首先递归添加最差的元素以获得所需的顺序。

cs = ["A", "B", "C"]


def subsets(xs):
    res = [[]]
    for x in xs[::-1]:
        res = [[x] + r for r in res] + res

    return res[:-1]


# [["A", "B", "C"], ["A", "B"], ["A", "C"], ["A"], ["B", "C"], ["B"], ["C"]]

在执行期间,res如下所示:

[[]]
[["C"],[]]
[["B","C"],["B"],["C"],[]]
...

或者,您可以依靠itertools.product来获得懒惰的解决方案。

from itertools import product


def lazy_subsets(xs):
    for ix in product(*([[True, False]] * len(xs))):
        yield [x for x, b in zip(xs, ix) if b]


res = list(lazy_subsets(cs))[:-1]

在这里,每个ixbool的列表,用作布尔掩码来过滤xsproduct产生ix的顺序与xs子集上赋予初始元素优先级的顺序一致。

答案 1 :(得分:0)

您可以通过优先级功能对组合进行排序,优先级功能定义为组合元素的原始索引的排序列表(索引越低优先级越高),最后用无穷大填充(因为我们要给长度较长的组合一个较小长度组合的机会):

from itertools import combinations

lst = ['A', 'B', 'C']
index = {l: i for i, l in enumerate(lst)}

def priority(c):
    return sorted([index[x] for x in c]) + [float('inf')] * (len(lst) - len(c))


result = sorted([c for i in range(1, len(lst) + 1) for c in combinations(lst, i)], key=priority)
print(result)
# [('A', 'B', 'C'), ('A', 'B'), ('A', 'C'), ('A',), ('B', 'C'), ('B',), ('C',)]

答案 2 :(得分:0)

有些笨拙,但这可以使用itertools.combinations ...

parentItem