您正在生成permutation of a multiset。
简单但幼稚的方法是使用itertools.permutations(),用一个集合来过滤掉重复的组合:
>>> from itertools import permutations
>>> seen = set()
>>> for combo in permutations([1] * 4 + [0] * 4):
... if combo not in seen:
... seen.add(combo)
... print combo
...
(1, 1, 1, 1, 0, 0, 0, 0)
(1, 1, 1, 0, 1, 0, 0, 0)
(1, 1, 1, 0, 0, 1, 0, 0)
(1, 1, 1, 0, 0, 0, 1, 0)
(1, 1, 1, 0, 0, 0, 0, 1)
(1, 1, 0, 1, 1, 0, 0, 0)
# ...
(0, 0, 1, 0, 1, 0, 1, 1)
(0, 0, 1, 0, 0, 1, 1, 1)
(0, 0, 0, 1, 1, 1, 1, 0)
(0, 0, 0, 1, 1, 1, 0, 1)
(0, 0, 0, 1, 1, 0, 1, 1)
(0, 0, 0, 1, 0, 1, 1, 1)
(0, 0, 0, 0, 1, 1, 1, 1)
或者,一次性生成整个序列:
set(permutations([1] * 4 + [0] * 4))
但这会丢失permutations 产生的顺序。
需要该集合,因为 permutations() 将 4 个 1 和 4 个 0 视为单独的字符,一个 1 与另一个交换被认为是唯一的排列。
您还可以使用序列中的排序来避免使用集合:
last = (1,) * 8
for combo in permutations([1] * 4 + [0] * 4):
if combo < last:
last = combo
print combo
这种方法在那个 2n 中是幼稚的!在我们只想要(2n 选择 n)个元素的地方产生排列。对于您的情况,这是 40320 个排列,我们只需要产生 70 个。