这是一个将文本翻译成中文的助手。
这是一种组合方法,它包括两个步骤:(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
,例如请参见
这里 或
这里。
itertools.product
- 但是我不理解最后一句话,为什么一些通常使用的元素不属于你所需的列表... - SpghttCd[0,0,1]
和[1,1,0]
都应该属于吗? - Himitertools.combinations_with_replacement(range(3),3)
开始,然后进行过滤,但毫无疑问会有更好的方法。 - Chris_Rands