减少构建字典/字符串的嵌套for循环(分支树样式)

时间:2014-09-18 15:53:57

标签: python for-loop nested-loops

对于最近的脚本,我不得不通过分支树迭代可能的流。我构建了一个字典,其中包含每个项目的运行状态,以便我进行评估。例如:

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))

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您希望在所有table字典值之间进行所有排列,以便您可以使用itertools模块查找更多 pythonic map以及{ {1}}用于连接它们的函数!

join

一些输出:

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)