【问题标题】:What is the best way to write a multiple nested for loops in Python在 Python 中编写多个嵌套 for 循环的最佳方法是什么
【发布时间】:2013-11-23 16:48:48
【问题描述】:

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

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,但无法得到我想要的,因为我的循环的所有开始/结束索引都取决于上一个级别。

【问题讨论】:

    标签: python optimization for-loop


    【解决方案1】:

    您可以使用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)]
    

    【讨论】:

    • 是的,我的错误只是阅读了标题并看到了您的答案然后实际上看到了他的代码
    • @JoelGreen 没关系 :)
    • @user3024444 不客气 :) 如果它真的对你有帮助,请考虑接受这个答案meta.stackexchange.com/a/5235/235416
    【解决方案2】:

    直接从 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....
    

    【讨论】:

      【解决方案3】:

      有时这种算法通常可以使用递归方法来实现。作为下一级迭代需要复杂测试的示例,请考虑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])
      

      而且你还知道关卡的数量(即皇后问题的棋盘大小)成为一个参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        • 2017-06-28
        • 1970-01-01
        • 2022-01-26
        • 2015-11-28
        相关资源
        最近更新 更多