有没有更快的方法在python中创建(0,1)组合列表?

时间:2016-12-08 02:29:51

标签: python

我想创建一个列表,其中插入的零组合位置如下:

l = [(0, 0, 0, 0, 1, 1),
     (0, 0, 0, 1, 0, 1),
     (0, 0, 0, 1, 1, 0),
     (0, 0, 1, 0, 0, 1),
     (0, 0, 1, 0, 1, 0),
     (0, 0, 1, 1, 0, 0),
     (0, 1, 0, 0, 0, 1),
     (0, 1, 0, 0, 1, 0),
     (0, 1, 0, 1, 0, 0),
     (0, 1, 1, 0, 0, 0),
     (1, 0, 0, 0, 0, 1),
     (1, 0, 0, 0, 1, 0),
     (1, 0, 0, 1, 0, 0),
     (1, 0, 1, 0, 0, 0),
     (1, 1, 0, 0, 0, 0)]

我可以使用

构建列表
[e for e in itertools.product(range(2), repeat=6) if sum(e)==2]

但是,当repeat的参数变大为20时,代码非常耗时。

我认为这可能是在内存中建立中间结果的问题? 我想知道有没有更好的方法来创建我需要的列表。 感谢。

2 个答案:

答案 0 :(得分:7)

以下函数返回所有n - 具有k元组的元组的列表。它适用于choose(50,2)的瞬间工作,例如:

def choose(n, k):
    if n < k or k < 0:
        return []
    elif n == 0:
        return [()]
    return \
        [(0,) + r for r in choose(n-1, k)] + \
        [(1,) + r for r in choose(n-1, k-1)]

以下是choose(6,2)的输出:

>>> choose(6,2)
[(0, 0, 0, 0, 1, 1), 
 (0, 0, 0, 1, 0, 1), 
 (0, 0, 0, 1, 1, 0), 
 (0, 0, 1, 0, 0, 1), 
 (0, 0, 1, 0, 1, 0), 
 (0, 0, 1, 1, 0, 0), 
 (0, 1, 0, 0, 0, 1), 
 (0, 1, 0, 0, 1, 0),
 (0, 1, 0, 1, 0, 0),
 (0, 1, 1, 0, 0, 0), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 1, 0), 
 (1, 0, 0, 1, 0, 0),
 (1, 0, 1, 0, 0, 0), 
 (1, 1, 0, 0, 0, 0)]

这与问题中的示例相同。

答案 1 :(得分:4)

非递归方式在大N时可能效果更好,可能更容易理解 - 我们只需选择k位激活。

In [43]: list(bits_on(6, 2))
Out[43]: 
[(1, 1, 0, 0, 0, 0),
 (1, 0, 1, 0, 0, 0),
 (1, 0, 0, 1, 0, 0),
 (1, 0, 0, 0, 1, 0),
 (1, 0, 0, 0, 0, 1),
 (0, 1, 1, 0, 0, 0),
 (0, 1, 0, 1, 0, 0),
 (0, 1, 0, 0, 1, 0),
 (0, 1, 0, 0, 0, 1),
 (0, 0, 1, 1, 0, 0),
 (0, 0, 1, 0, 1, 0),
 (0, 0, 1, 0, 0, 1),
 (0, 0, 0, 1, 1, 0),
 (0, 0, 0, 1, 0, 1),
 (0, 0, 0, 0, 1, 1)]

给了我

In [46]: %time len(list(bits_on(200,2)))
CPU times: user 132 ms, sys: 0 ns, total: 132 ms
Wall time: 131 ms
Out[46]: 19900

In [47]: %time len(list(choose(200,2)))
CPU times: user 9.4 s, sys: 0 ns, total: 9.4 s
Wall time: 9.4 s
Out[47]: 19900

In [48]: set(bits_on(200,2)) == set(choose(200,2))
Out[48]: True

{{1}}