【问题标题】:Variable for loops with recursion带有递归的循环变量
【发布时间】:2012-10-12 05:37:57
【问题描述】:

希望通过递归执行以下操作,以便我可以改变“for”循环的数量:

n = 5
out = []
for i in range(n):
    for j in range(i,n):
        for k in range(j,n):
            out.append([i,j,k])

返回

out =   [[0 0 0]
         [0 0 1]
         [0 0 2]
         [0 0 3]
         [0 0 4]
         [0 1 1]
         [0 1 2]
         [0 1 3]
         [0 1 4]
         [0 2 2]
         [0 2 3]
         [0 2 4]
         [0 3 3]
         [0 3 4]
         [0 4 4]
         [1 1 1]
         [1 1 2]
         [1 1 3]
         [1 1 4]
         [1 2 2]...]

例如

def Recurse(n, p):
  # where p is the number of for loops
  some magic recursion 
  return out

我查看了其他一些递归问题,但很难找到解决方案。

【问题讨论】:

    标签: python recursion


    【解决方案1】:

    不使用递归,而是使用itertools.product(),相当于生成器表达式中的嵌套for循环:

    >>> import itertools
    >>> list(itertools.product(range(3), repeat=2))
    [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
    >>> list(itertools.product(range(3), repeat=3))
    [(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), (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), (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)]
    

    编辑:没有意识到这实际上不是笛卡尔积,因为内部循环使用外部变量来开始范围,这是一种可能性,但效率不如它可能是因为它生成了额外的值并且需要检查每个值是否有效:

    def nested_loops(n, num_loops):
        prod = itertools.product(range(n), repeat=num_loops)
        for item in prod:
            if all(item[i] <= item[i+1] for i in range(num_loops-1)):
                yield item
    
    >>> list(nested_loops(3, 2))
    [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]
    >>> list(nested_loops(3, 3))
    [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 1), (0, 1, 2), (0, 2, 2), (1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]
    

    【讨论】:

    • 虽然,OP 的期望输出不是笛卡尔积——没有 (1,0,0)。检查范围参数。
    • @DSM - 没错!没有注意到在第一次通读时,我将开始进行编辑。
    • @JoranBeasley XD 不是作业。尝试为最小二乘近似创建变量矩阵,其中 for 循环的数量设置顺序(二次、三次等)。输出是线性矩阵的索引。这可能没有多大意义,这就是我把它排除在 Q 之外的原因
    • 在 Python 2.7+ 中。你可以写itertools.combinations_with_replacment(range(n), w),我想。
    • @DSM 我认为您是对的,将其添加为 +1 的答案,这比我的破解解决方案要好得多!
    【解决方案2】:

    @DSM 有更好的答案(但在 cmets 中)

    但是这里是一个简单的递归解决方案,以防万一有人努力解决它

    def f(n, p, start=0):
        if p==0:
            yield []
        else:
            for i in range(start, n):
                for j in f(n, p-1, i):
                    yield [i]+j
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 2012-11-17
      • 2014-05-08
      • 1970-01-01
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多