python中列表的所有补充子集

时间:2017-10-04 01:07:25

标签: python python-3.x subset combinations combinatorics

我不确定'补充'是否是正确的词,但我会用一个例子解释我的问题。假设我们的列表是:

[1,2,3,4]

我想要找到的是:

[1], [2], [3], [4]
[1,2], [3], [4]
[1,3], [2], [4]
...
[1,2], [3,4]
[1,3], [2,4]
...
[1,2,3], [4]
[1,2,4], [3]
...
[1,2,3,4]

换句话说,我试图获得所有列表,以便它们一起具有初始列表的所有元素。

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用Raymond Hettinger's partition recipe查找所有分区。我稍微修改了它以使用Python3。我还添加了partition_permutations来查找输入的所有排列的分区x

import pprint
import itertools as IT

def partition(iterable, chain=IT.chain, map=map):
    """
    http://code.activestate.com/recipes/576795/ (Raymond Hettinger)
    >>> list(partition('abcd'))
    [['abcd'],
     ['a', 'bcd'],
     ['ab', 'cd'],
     ['abc', 'd'],
     ['a', 'b', 'cd'],
     ['a', 'bc', 'd'],
     ['ab', 'c', 'd'],
     ['a', 'b', 'c', 'd']]
    """
    s = iterable if hasattr(iterable, '__getitem__') else tuple(iterable)
    n = len(s)
    first, middle, last = [0], range(1, n), [n]
    getitem = s.__getitem__
    return [list(map(getitem, map(slice, chain(first, div), chain(div, last))))
            for i in range(n) for div in IT.combinations(middle, i)]

def partition_permutations(iterable, ordered_partitions=False):
    result = set()
    for perm in IT.permutations(iterable):
        for item in partition(perm):
            if ordered_partitions:
                result.add(tuple(item))
            else:
                result.add(tuple(sorted(item)))
    result = [list(map(list, item)) for item in result]
    result = sorted(result)
    return result


x = [1,2,3,4]
result = partition_permutations(x, ordered_partitions=True)
pprint.pprint(result)
print(len(result))

产生73项:

[[[1], [2], [3], [4]],
 [[1], [2], [3, 4]],
 [[1], [2], [4, 3]],
 [[1], [2, 3], [4]],
 [[1], [2, 3, 4]],
 [[1], [2, 4], [3]],
 [[1], [2, 4, 3]],
 [[1], [3], [4, 2]],
 [[1], [3, 2], [4]],
 [[1], [3, 2, 4]],
 [[1], [3, 4, 2]],
 [[1], [4, 2, 3]],
 [[1], [4, 3, 2]],
 [[1, 2], [3], [4]],
 [[1, 2], [3, 4]],
 [[1, 2], [4, 3]],
 [[1, 2, 3], [4]],
 [[1, 2, 3, 4]],
 [[1, 2, 4], [3]],
 [[1, 2, 4, 3]],
 [[1, 3], [2], [4]],
 [[1, 3], [2, 4]],
 [[1, 3], [4, 2]],
 [[1, 3, 2], [4]],
 [[1, 3, 2, 4]],
 [[1, 3, 4], [2]],
 [[1, 3, 4, 2]],
 [[1, 4], [2], [3]],
 [[1, 4], [2, 3]],
 [[1, 4], [3, 2]],
 [[1, 4, 2], [3]],
 [[1, 4, 2, 3]],
 [[1, 4, 3], [2]],
 [[1, 4, 3, 2]],
 [[2], [3], [4, 1]],
 [[2], [3, 1], [4]],
 [[2], [3, 1, 4]],
 [[2], [3, 4, 1]],
 [[2], [4, 1, 3]],
 [[2], [4, 3, 1]],
 [[2, 1], [3], [4]],
 [[2, 1], [3, 4]],
 [[2, 1], [4, 3]],
 [[2, 1, 3], [4]],
 [[2, 1, 3, 4]],
 [[2, 1, 4], [3]],
 [[2, 1, 4, 3]],
 [[2, 3], [4, 1]],
 [[2, 3, 1], [4]],
 [[2, 3, 1, 4]],
 [[2, 3, 4, 1]],
 [[2, 4], [3, 1]],
 [[2, 4, 1], [3]],
 [[2, 4, 1, 3]],
 [[2, 4, 3, 1]],
 [[3], [4, 1, 2]],
 [[3], [4, 2, 1]],
 [[3, 1], [4, 2]],
 [[3, 1, 2], [4]],
 [[3, 1, 2, 4]],
 [[3, 1, 4, 2]],
 [[3, 2], [4, 1]],
 [[3, 2, 1], [4]],
 [[3, 2, 1, 4]],
 [[3, 2, 4, 1]],
 [[3, 4, 1, 2]],
 [[3, 4, 2, 1]],
 [[4, 1, 2, 3]],
 [[4, 1, 3, 2]],
 [[4, 2, 1, 3]],
 [[4, 2, 3, 1]],
 [[4, 3, 1, 2]],
 [[4, 3, 2, 1]]]

请注意partition_permutations将每个分区中的项目视为 无序的。也就是说,例如[[1,4], [2,3]][[2,3], [1,4]] 作为同一分区处理。如果那不是你想要的,那么改变

result = partition_permutations(x)

result = partition_permutations(x, ordered_partitions=True)