在Python中生成部分子集

时间:2014-07-07 19:27:50

标签: python python-2.7

忏悔:这是为了上课。

我正在尝试生成长度为1的所有子集 - 长度(全套),但它们必须按顺序排列。

因此,输入(4,2)时,结果将是有效的 (4),(4,2)和(2)。 不会是 (4,4)(2,2)或(2,4)

ETA (4,2,2)也应该返回(2,2)。

长度未预先确定。

我现在拥有的:

def gen_all_partials(outcomes, length):
    """
    Iterative function that enumerates the set of all sequences of
    outcomes of lengths up to given length.
    """

    answer_set = set([()])
    for dummy_idx in range(length):
        temp_set = set()
        for partial_sequence in answer_set:
            for item in outcomes:
                new_sequence = list(partial_sequence)
                new_sequence.append(item)
                temp_set.add(tuple(new_sequence))
        answer_set = temp_set
    return answer_set

这部分是通过给定的功能获得的。我不明白Python是如何迭代第二个#34中的空集;对于"环。除了"右"之外,该当前代码输出(4,4),(2,2)和(2,4)。答案。

我在挂起的循环上挂起并跟踪多个计数器,并为所需的输出设置不同的长度。

我也试过这个:

def gen_all_partials(outcomes, length):
    """
    Iterative function that enumerates the set of all sequences of
    outcomes of lengths up to given length.
    """

    answer_set = set([()])
    for dummy_idx in range(length):
        temp_set = set()
        for partial_sequence in answer_set:
            for item in outcomes:
                new_sequence = list(partial_sequence)
                new_sequence.append(item)
                if new_sequence not in temp_set:
                    temp_outcomes = list(outcomes[:])
                    add_to_set = True
                    for val in new_sequence:
                        if val in temp_outcomes:
                            order_list = []
                            for dummy_bit in val:
                                order_list.append(val.index(dummy_bit)) 
                                if order_list == order_list.sort():
                                    temp_outcomes.remove(val)
                                else:
                                    add_to_set = False
                        else: 
                            add_to_set = False
                    if add_to_set:
                        temp_set.add(tuple(new_sequence))
        answer_set = temp_set
    return answer_set

2 个答案:

答案 0 :(得分:3)

从有用的itertools recipes

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

这包括空集,但你可以轻而易举地改变range来处理它。

答案 1 :(得分:2)

这是一种使用递归的方法,不过您可以使用循环迭代地执行此操作,并加入每个n的列表:

a = [4,2]

def subseqs(x):
    def go(x, n):
        return zip(*(x[i:] for i in range(n))) + go(x, n-1) if n else []
    return go(x, len(x))

print subseqs(a)   # [(4, 2), (4,), (2,)]

或使用列表理解:

print sum([zip(*(a[i:] for i in range(n))) for n in range(len(a)+1)], [])