Python 所有复杂列表的组合

Python 所有复杂列表的组合,python,combinatorics,Python,Combinatorics,我想找到以下列表的所有可能组合: data = ['a','b','c','d'] 我知道这看起来很简单,可以通过以下代码实现: comb = [c for i in range(1, len(data)+1) for c in combinations(data, i)] 但我想要的实际上是一种给列表数据的每个元素两种可能性的方法('a'或'-a') 组合的示例可以是['a','b'],['-a','b'],['a','b','-c']等。 当然,如果没有下面这种情况,一旦生成了规则组合

我想找到以下列表的所有可能组合:

data = ['a','b','c','d'] 
我知道这看起来很简单,可以通过以下代码实现:

comb = [c for i in range(1, len(data)+1) for c in combinations(data, i)]
但我想要的实际上是一种给列表数据的每个元素两种可能性的方法(
'a'
'-a'

组合的示例可以是
['a','b']
['-a','b']
['a','b','-c']
等。
当然,如果没有下面这种情况,一旦生成了规则组合,就可以进行第二次传递,生成带有“否定”的组合。我认为它就像一个二进制数,列表中的元素数就是位数。通过0b0001、0b0010等从0b0000到0b1111进行计数,无论在哪里设置了位,在结果中对该元素求反。这将为长度为n的每个输入组合生成2^n个组合。

您可以编写一个生成器函数,该函数接受一个序列并生成每个可能的否定组合。像这样:

import itertools
def negations(seq):
    for prefixes in itertools.product(["", "-"], repeat=len(seq)):
        yield [prefix + value for prefix, value in zip(prefixes, seq)]

print list(negations(["a", "b", "c"]))
结果(为清晰起见修改了空格):

您可以通过以下方式将其集成到现有代码中

comb = [x for i in range(1, len(data)+1) for c in combinations(data, i) for x in negations(c)]

我的解决方案基本上与。生成所有组合的列表后

comb = [c for i in range(1, len(data)+1) for c in combinations(data, i)]
梳的每个元素生成所有可能的正/负组合。通过迭代组合的总数,
2**(N-1)
,并将其视为一个二进制数,其中每个二进制数字代表一个元素的符号。(例如,两元素列表将有4种可能的组合,0到3,由
0b00=>(+,+)
0b01=>(-,+)
0b10=>(+,-)
0b11=>(-)
)表示)


这里有一条路线,但很难遵循:

from itertools import product

comb = [sum(t, []) for t in product(*[([x], ['-' + x], []) for x in data])]
首先将
数据
映射到它们在结果中可以变成什么的列表。然后使用
产品*
获得所有可能。最后,用
sum
展平每个组合

def twocombinations(it):
    sign = lambda c, i: "-" if c & 2**i else ""
    l = list(it)

    if len(l) < 1:
        return

    # for each possible combination, make a tuple with the appropriate
    # sign before each element
    for c in range(2**(len(l) - 1)):
        yield tuple(sign(c, i) + el for i, el in enumerate(l))
l = itertools.chain.from_iterable(map(twocombinations, comb))
from itertools import product

comb = [sum(t, []) for t in product(*[([x], ['-' + x], []) for x in data])]