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])]