我想在2d数组中组合1和0,如下所示:
[[ 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和4个的组合。我查看了itertools
模块permutations()
和combinations()
,但无法找到合适的功能来执行此组合。
答案 0 :(得分:4)
您还可以使用combinations
直接生成唯一组合:
n = 8
n1 = 4
for x in itertools.combinations( xrange(n), n1 ) :
print [ 1 if i in x else 0 for i in xrange(n) ]
[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]
...
[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]
这比permutations
更有效,因为您不会迭代不需要的解决方案。
直觉是你试图找到所有可能的方法,以长度8的顺序拟合四个" 1" s;这是combinations的确切定义。该数字为C(8,4)=8! / (4! * 4!) = 70
。相反,使用permutations
的解决方案会迭代8! = 40,320
个候选解决方案。
答案 1 :(得分:1)
您正在制作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
视为单个字符,而与另一个{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。