2013-04-16 20 views
3

的Python:蟒蛇:執行一個通用的多維循環

如何執行效率多維循環,當指數的循環數量是動態的。

假設含有每個變量

var_size = [ 3, 4, 5 ] 

的大小和功能「環」,這將稱之爲「F(current_state)」的每一個點陣列var_size。

def f(state): print state 
    loop(var_size, f) 

該調用會打電話˚F以下順序:

f([ 0, 0, 0]) 
f([ 0, 0, 1]) 
f([ 0, 0, 2]) 
f([ 0, 1, 0]) 
etc.... 
+3

我想你可以用'itertools.product'來管理這個 - itertools.starmap'也可能有用。 – mgilson

回答

0

做初始化爲0的列表,在var_size儘可能多的條目。我們把這個列表當作'翻轉器'的列表 - 我們增加列表中的最後一個,直到它溢出它的極限(又名var_size在同一點到列表中)。如果是這樣,我們將它設置爲0,然後重複增量/溢出檢查,直到我們不溢出(重置'我們正在查看哪個轉向'變量回到最後並繼續)或溢出所有的條目列表(我們完成了,我們一直圍繞着),然後執行下一個呼叫。

我不知道這是最佳的還是pythonic,但它是O(n)。

4

你可以用itertools.product做到這一點:

>>> print list(itertools.product(*(range(x) for x in reversed([3,4,5])))) 
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 3, 0), (0, 3, 1), (0, 3, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 3, 0), (1, 3, 1), (1, 3, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2), (2, 3, 0), (2, 3, 1), (2, 3, 2), (3, 0, 0), (3, 0, 1), (3, 0, 2), (3, 1, 0), (3, 1, 1), (3, 1, 2), (3, 2, 0), (3, 2, 1), (3, 2, 2), (3, 3, 0), (3, 3, 1), (3, 3, 2), (4, 0, 0), (4, 0, 1), (4, 0, 2), (4, 1, 0), (4, 1, 1), (4, 1, 2), (4, 2, 0), (4, 2, 1), (4, 2, 2), (4, 3, 0), (4, 3, 1), (4, 3, 2)] 

請注意,我產生tuple s,而不是list S,但這是容易解決,如果你真的需要。

所以,對我來說,它看起來像你想:

map(f,itertools.product(*map(range,reversed(var_size)))) 
+0

爲什麼顛倒()? – user9876

+0

@ user9876 - 因爲看起來OP希望'range(3)'在快速循環中。 – mgilson

0

此代碼的工作 - 它沒有創建列表的優勢。然而,它並不那麼優雅....

任何想法如何讓這個更好?

def loop(var_size, f): 
    nb = len(var_size) 
    state = [0]*nb 
    ok = True 
    while ok: 
     f(state) 
     for i in range(nb-1, -1, -1): 
      state[i] = state[i]+1 
      if state[i] < var_size[i]: 
       break 
      else: 
       if i == 0: 
        ok = False 
        break 
       else: 
        state[i] = 0 

var_size = [3,4,5] 
def f(state): 
    print state 

loop(var_size, f)