2014-09-18 24 views
1

對於最近的腳本,我必須遍歷分支樹中的可能流。我建立了一個包含每個項目運行狀態的字典,以便我評估。例如:減少構建字典/字符串的嵌套循環(分支樹樣式)

for a in range(0, 2): 
    for b in range(0, 2): 
    for c in range(0, 2): 
     for d in range(0, 2): 
     ... 
     run = [a,b,c,d ...] 

不幸的是,它起初很小,但發展到十幾個州。這怎麼能減少以消除所有的嵌套循環?

如果某些州有3個或4個州而不是2個州,那麼類似的答案會有所不同嗎?

同樣,如果每個循環都來自函數列表,那麼同樣的問題會受到怎樣的影響?我懷疑它會是一樣的。例如:

def leet_lookup(char): 
    table = {"a": ["a","A","@"], 
      "b": ["b", "B", "8"], 
      "c": ["c", "C", "<"], 
      "e": ["e", "E", "3"], 
      "i": ["i", "I", "1"], 
      "l": ["l", "L", "1"], 
      "o": ["o", "O", "0"], 
      "t": ["t", "T", "7"] } 
    try: 
     result = table[char.lower()] 
    except KeyError: 
     result = [char.lower(), char.upper()] 
    return result 

result = [] 
# V o l l e y b a l l = 10 chars 
for c1 in leet_lookup('v'): 
    for c2 in leet_lookup('o'): 
    for c3 in leet_lookup('l'): 
     for c4 in leet_lookup('l'): 
     for c5 in leet_lookup('e'): 
      for c6 in leet_lookup('y'): 
      for c7 in leet_lookup('b'): 
       for c8 in leet_lookup('a'): 
       for c9 in leet_lookup('l'): 
        for c10 in leet_lookup('l'): 
        result.append("%s%s%s%s%s%s%s%s%s%s" % (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)) 

回答

3

再次,這是一個問題乞求從itertools解決方案。

對於第一個問題,只需使用product即可。

from itertools import product 
for run in product(range(2), repeat=5): 
    print(run) 

# (0, 0, 0, 0, 0) 
# (0, 0, 0, 0, 1) 
# (0, 0, 0, 1, 0) 
# etc. 

如果每個指示器更多的狀態,或者a)每個指示器具有相同數目的狀態並且可以簡單地改變的range參數,或b)不同的指標有狀態的不同的數字,在此情況下你可以做類似於下面的答案,將leet_lookup呼叫替換爲range,並且具有狀態號碼列表而不是lookups

對於第二個,您可能想要構建一個迭代列表,然後您可以使用product

lookups = ['v', 'o', 'l', 'l'] 
items = [leet_lookup(a) for a in lookups] 
for c in product(*items): 
    print(c) 

# ('v', 'o', 'l', 'l') 
# ('v', 'o', 'l', 'L') 
# ('v', 'o', 'l', '1') 
# ('v', 'o', 'L', 'l') 
# etc. 

一般情況下,如果你有涉及到任何種類的組合或迭代器轉型的問題,您應該首先尋找一個itertools功能或recipe

+0

很好的解決方案壽! – soupault 2014-09-18 16:12:22

+0

優秀的答案和建議,第二個特別令人望而生畏,但您的解決方案非常出色!謝謝 – 2014-09-18 17:53:46

0

你希望所有table的字典值之間的所有排列,所以你可以使用itertools模塊發現,這是更Python的mapjoin功能將它們串聯!

import itertools 
table = {"a": ["a","A","@"], 
     "b": ["b", "B", "8"], 
     "c": ["c", "C", "<"], 
     "e": ["e", "E", "3"], 
     "i": ["i", "I", "1"], 
     "l": ["l", "L", "1"], 
     "o": ["o", "O", "0"], 
     "t": ["t", "T", "7"] } 

for pro in itertools.product(table['a'],table['b'],table['c'],table['e'],table['i'],table['l'],table['o'],table['t']): 
    print ''.join(pro) 

一些輸出:

@8<3Il0T 
@8<3Il07 
@8<3ILot 
@8<3ILoT 
@8<3ILo7 
@8<3ILOt 
@8<3ILOT 
@8<3ILO7 
@8<3IL0t 
... 
+0

感謝您的解決方案。但是,這看起來只是在表格中對字符進行排列,並且不會根據需要使用提供的字符串。 – 2014-09-18 17:56:25