Python 在列表中查找2^n-2个元素组合

Python 在列表中查找2^n-2个元素组合,python,list,combinations,apriori,Python,List,Combinations,Apriori,我有以下清单: list1 = ['g1','g2','g3','g4'] 我想找到2^n-2组合,其中n是列表中项目的总数。对于n=4,结果应为2^4-2=14,即14个组合 这些组合是: [[['g1'],['g2','g3','g4']],[['g2'],['g1','g3','g4']], [['g3'],['g1','g2','g4']],['g4'],['g1','g2','g3']],[['g1','g2'],['g3','g4']],[['g1','g3'],['g2','g4

我有以下清单:

list1 = ['g1','g2','g3','g4']
我想找到
2^n-2
组合,其中
n
是列表中项目的总数。对于
n=4
,结果应为
2^4-2=14
,即14个组合

这些组合是:

[[['g1'],['g2','g3','g4']],[['g2'],['g1','g3','g4']], [['g3'],['g1','g2','g4']],['g4'],['g1','g2','g3']],[['g1','g2'],['g3','g4']],[['g1','g3'],['g2','g4']],[['g1','g4'],['g3','g4']],[['g2','g3'],['g1','g4']],
[['g2','g4'],['g1','g3']],[['g3','g4'],['g1','g2']],[['g1','g2','g3'],['g4']],[['g2','g3','g4'],['g1']],[['g3','g4','g1'],['g2']],[['g4','g1','g2'],['g3']]]
我知道一种方法: 在第一次迭代中,将单个元素放入一个列表中,并将其放入第二个列表中的其他元素:
['g1']、['g2'、'g3'、'g4']
在第二次迭代中,在一个列表中取2个元素,在第二个列表中取其他元素<代码>['g1','g2'],['g1','g4'] 还有其他方法吗?? 我正在用python编写这个程序。
我的方法代价高昂。是否有任何库方法可以快速执行此操作。

以下是使用
itertools的函数方法

import itertools as iter

list1 = ['g1', 'g2', 'g3', 'g4']
combinations = [iter.combinations(list1, n) for n in range(1, len(list1))]
flat_combinations = iter.chain.from_iterable(combinations)
result = map(lambda x: [list(x), list(set(list1) - set(x))], flat_combinations)
# [[['g1'], ['g4', 'g3', 'g2']], [['g2'], ['g4', 'g3', 'g1']], [['g3'], ['g4', 'g2', 'g1']],...
len(result)
# 14

下面是一个使用
itertools

import itertools as iter

list1 = ['g1', 'g2', 'g3', 'g4']
combinations = [iter.combinations(list1, n) for n in range(1, len(list1))]
flat_combinations = iter.chain.from_iterable(combinations)
result = map(lambda x: [list(x), list(set(list1) - set(x))], flat_combinations)
# [[['g1'], ['g4', 'g3', 'g2']], [['g2'], ['g4', 'g3', 'g1']], [['g3'], ['g4', 'g2', 'g1']],...
len(result)
# 14
itertools.组合(iterable,r)

从输入iterable返回元素的r长度子序列。 组合按字典排序顺序发出。因此,如果输入 iterable被排序后,组合元组将以排序的方式生成 秩序

输出:

你可以试试这个

itertools.组合(iterable,r)

从输入iterable返回元素的r长度子序列。 组合按字典排序顺序发出。因此,如果输入 iterable被排序后,组合元组将以排序的方式生成 秩序

输出:


你可以试试这个

我喜欢中国程序员的解决方案(我想)。以下是我自己的解决方案:

import itertools


def flatten(*z):
    return z


list1 = ['g1','g2','g3','g4']

sublists = []
for i in range(1, len(list1)):
    sublists.extend(itertools.combinations(list1, i))

pairs = []
for a, b in itertools.product(sublists, sublists):
    if len(a) + len(b) == len(list1) and \
    len(set(flatten(*a, *b))) == len(list1):
        pairs.append((a, b))

print(pairs, len(pairs))

我喜欢中国程序员的解决方案(我猜)。以下是我自己的解决方案:

import itertools


def flatten(*z):
    return z


list1 = ['g1','g2','g3','g4']

sublists = []
for i in range(1, len(list1)):
    sublists.extend(itertools.combinations(list1, i))

pairs = []
for a, b in itertools.product(sublists, sublists):
    if len(a) + len(b) == len(list1) and \
    len(set(flatten(*a, *b))) == len(list1):
        pairs.append((a, b))

print(pairs, len(pairs))


你说的昂贵是什么意思?生成组合的算法复杂性将是指数级的,无论实现如何。我更新了我的答案以更好地反映您的需求。您所说的昂贵是什么意思?生成组合的算法复杂度将是指数级的,与实现无关。我更新了我的答案,以更好地反映您的需求。如何获得元组的第二部分?我不完全确定这个稍微令人困惑的问题是否需要。他关注的是组合,它们只是元组的第一部分。OP的例子是一个有序集分区列表,正好有两部分。这只会生成每个分区的一半。您需要将每个子集/组合与其补码配对。我相信这个问题要求可能的配对数量。因此,这个答案可能是完整解决方案的一部分;或者有更好的解决办法。@hyades我现在补充说。你如何得到元组的第二部分?我不完全确定这个稍微令人困惑的问题是否需要。他关注的是组合,它们只是元组的第一部分。OP的例子是一个有序集分区列表,正好有两部分。这只会生成每个分区的一半。您需要将每个子集/组合与其补码配对。我相信这个问题要求可能的配对数量。因此,这个答案可能是完整解决方案的一部分;或者可能有更好的解决办法。@hyades我现在补充说。这与我的答案几乎相同,并且没有考虑OP希望长度1的所有组合都达到
len(list1)
。再加上它,我的问题的OP就很简单了。这里我不需要所有的nC2元素,我需要的是一个列表或元组中的第一个元素和第二个列表或元组中的其他元素。('g1'),('g2','g3','g4')在第二次迭代中,我想要('g1','g2'),('g3','g4')等等@宏杰李 这是非常简单的,我已经发布了一个答案。这与我的答案几乎相同,并且没有考虑到OP希望所有长度1的组合都达到
len(list1)
。再加上它,我的问题的OP就非常简单了。这里我不需要所有的nC2元素,我需要的是一个列表或元组中的第一个元素和第二个列表或元组中的其他元素。('g1'),('g2','g3','g4')在第二次迭代中,我想要('g1','g2'),('g3','g4')等等@宏杰李 事实上,这很简单,我已经发布了一个这样的答案。由于您将powerset(减去空的和完整的集合)具体化为一个列表,因此您可以使用其自身的反面来
zip
它:比如
pairs=list(zip(子列表,反转(子列表)))
而不是使用
itertools.product
和过滤。由于您将powerset(减去空的和完整的集合)具体化为一个列表,因此您可以使用
zip
将其本身反向:如
pairs=list(zip(子列表,反向(子列表))
而不是使用
itertools.product
和过滤。