这是(a)查找列表[k_1,…,k_n]使得每个k_i等于k_(i-1)或k_(i-1)1,以及(b)找到那些的唯一排列的组合名单.
第一个可以使用递归函数完成:
def combinations(n, k=0):
if n > 1:
yield from ([k] + res for i in (0, 1)
for res in combinations(n-1, k+i))
else:
yield [k]
对于具有n个元素的列表,将有2 ^(n-1)个这样的组合:
>>> list(combinations(2))
[[0, 0], [0, 1]]
>>> list(combinations(3))
[[0, 0, 0], [0, 0, 1], [0, 1, 1], [0, 1, 2]]
>>> list(combinations(4))
[[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 1], [0, 0, 1, 2], [0, 1, 1, 1], [0, 1, 1, 2], [0, 1, 2, 2], [0, 1, 2, 3]]
将它与itertools.permutations结合并过滤掉重复项以获得最终结果:
import itertools
def all_combinations(n):
return (x for combs in combinations(n)
for x in set(itertools.permutations(combs)))
例:
>>> list(all_combinations(3))
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (1, 0, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0), (0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]
>>> sum(1 for _ in all_combinations(4))
75
>>> sum(1 for _ in all_combinations(5))
541
注意:生成所有n!即使对于稍大的n值,排列然后过滤重复项也可能非常浪费.有更聪明的方法可以只生成可以用来代替itertools.permutations的唯一排列,参见例如. here或here.