2016-12-08 46 views
2

我想與那些結合地方零插入如下創建列表:有沒有更快的方式來創建(0,1)組合在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個大,該代碼非常耗時。

我認爲這可能是在內存中建立中間結果的問題? 我想知道有沒有更好的方法來創建我需要的列表。 謝謝。

+0

似乎沒什麼問題。你可能只是有一個大對象。 – TigerhawkT3

+1

是的,由於您的方法會生成所有可能的二進制序列,然後用兩個1進行挑選,所以這會變得越來越慢。你最好直接構建序列。 – pvg

回答

4

非遞歸方式在大N時可能會更好,並且可能會更容易理解 - 我們只選擇k位來激活。

import itertools 

def bits_on(n, k): 
    for which_on in itertools.combinations(range(n), k): 
     out = [0]*n 
     for index in which_on: 
      out[index] = 1 
     yield tuple(out) 

這給了我

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 
+0

如果你打算使用itertools,你可以像'list(set(itertools.permutations([0,0,0,1,1])))' – pvg

+1

這樣做。如果您做了相反的操作,您也可以按字典順序生成它們:選擇'n-k'位以_deactivate_。 –

+1

@pvg:這樣做效率很低..對我來說,只需要執行'list(set(itertools.permutations([0] * 8 + [1] * 2)))''''。 – DSM

7

以下函數返回所有n -tuples與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)] 

這等同於這個問題的例子。

相關問題