在Python中编写多个嵌套for循环的最佳方法是什么

时间:2013-11-23 08:27:08

标签: python optimization for-loop

我正在编写一个代码,我需要使用嵌套循环,如下所示:

for r in range(m):
   for s in range(r+1, m):
      for t in range(s+1, m):
         for u in range(t+1, m):
            for v in range(u+1, m):
                  arr.append([r,s,t,u,v])

但是这个传统的嵌套循环看起来很难看。有没有办法用更少的线执行相同的操作?

我看了一下itertools.product但是我无法得到我想要的东西,因为我的循环的所有开始/结束索引都取决于之前的级别。

3 个答案:

答案 0 :(得分:5)

您可以使用itertools.combinations,第二个参数是您想要执行的循环数。

from itertools import combinations
for item in combinations("ABCD", 3):
    print item

<强>输出

('A', 'B', 'C')
('A', 'B', 'D')
('A', 'C', 'D')
('B', 'C', 'D')

因此,使用列表理解,整个代码就像这样

[list(item) for item in combinations("ABCD", 3)]

答案 1 :(得分:0)

直接从itertools.combinations创建数组,例如使用n = 8:

>>> from itertools import combinations
>>> arr = [i for i in combinations(range(8), 5)]
>>> arr
[(0, 1, 2, 3, 4), (0, 1, 2, 3, 5), (0, 1, 2, 3, 6), (0, 1, 2, 3, 7), (0, 1, 2, 4, 5), (0, 1, 2, 4, 6), (0, 1, 2, 4, 7), (0, 1, 2, 5, 6), (0, 1, 2, 5, 7), (0, 1, 2, 6, 7), (0, 1, 3, 4, 5), (0, 1, 3, 4, 6), (0, 1, 3, 4, 7), (0, 1, 3, 5, 6), (0, 1, 3, 5, 7), (0, 1, 3, 6, 7), (0, 1, 4, 5, 6), (0, 1, 4, 5, 7), (0, 1, 4, 6, 7), (0, 1, 5, 6, 7), (0, 2, 3, 4, 5), (0, 2, 3, 4, 6), (0, 2, 3, 4, 7), (0, 2, 3, 5, 6), (0, 2, 3, 5, 7), (0, 2, 3, 6, 7), (0, 2, 4, 5, 6), (0, 2, 4, 5, 7), (0, 2, 4, 6, 7), (0, 2, 5, 6, 7), (0, 3, 4, 5, 6), (0, 3, 4, 5, 7), (0, 3, 4, 6, 7), (0, 3, 5, 6, 7), (0, 4, 5, 6, 7), (1, 2, 3, 4, 5), (1, 2, 3, 4, 6), (1, 2, 3, 4, 7), (1, 2, 3, 5, 6), (1, 2, 3, 5, 7), (1, 2, 3, 6, 7), (1, 2, 4, 5, 6), (1, 2, 4, 5, 7), (1, 2, 4, 6, 7), (1, 2, 5, 6, 7), (1, 3, 4, 5, 6), (1, 3, 4, 5, 7), (1, 3, 4, 6, 7), (1, 3, 5, 6, 7), (1, 4, 5, 6, 7), (2, 3, 4, 5, 6), (2, 3, 4, 5, 7), (2, 3, 4, 6, 7), (2, 3, 5, 6, 7), (2, 4, 5, 6, 7), (3, 4, 5, 6, 7)]
>>> 

如果您正在寻找大数字,您可能最好编写一个生成器来为您迭代它或直接使用提供的生成器:

arr = [i for i in combinations(range(8), 5)]
for i in arr:
   # whatever you were going to use arr for....

答案 2 :(得分:0)

有时这种算法通常可以使用递归方法实现。作为下一级迭代需要复杂测试的示例,请考虑eight-queens问题解决方案:

for col0 in range(8):
    for col1 in range(8):
        if col1 != col0 and not same_diag(0, col0, 1, col1):
            for col2 in range(8):
                if (col2 != col1 and
                    col2 != col0 and
                    not same_diag(0, col0, 2, col0) and
                    not same_diag(1, col1, 2, col2)):
                    for col3 in range(8):
                        ... same pattern up to col7 ...

这个重复的代码可以用

来解决
def find_solution(i, free_cols, placed_queens):
    if i == 8:
        print_solution(placed_queens)
    else:
        for col in free_cols:
            if not any(same_diag(i, col, j, q)
                       for j, q in enumerate(placed_queens)):
                find_solution(i+1,
                              free_cols - set([col]),
                              placed_queens + [col])

并且您还可以获得级别数(即皇后问题的电路板大小)成为参数。