我想创建一个列表,其中插入的零组合位置如下:
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时,代码非常耗时。
我认为这可能是在内存中建立中间结果的问题? 我想知道有没有更好的方法来创建我需要的列表。 感谢。
答案 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}}