Python中数组中1和0的组合

时间:2014-07-07 11:50:17

标签: python python-2.7 combinations itertools

我想在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(),但无法找到合适的功能来执行此组合。

2 个答案:

答案 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。