有关Python递归函数课程的问题

时间:2019-03-27 08:42:49

标签: python recursion

我正在实现一种算法,以查找n个元素中所有m个元素的所有组合。

我已经通过答案验证了整个代码,但是由于没有注释,所以有些部分很难理解,所以我写了一个问题。

例如,对于输入,n = 7,对于to_pick,n = 4,因此smallest = 0是因为函数内的len(picked) == 0。然后,如果将smallest(0)插入了for语句的选取列表中,并且再次to_pick == 0pick(n, picked, to_pick-1)中插入了选取,则返回选取。 ([0,1,2,3])

但是接下来,我无法理解拣选过程为[0,1,2,4]。当to_pick == 0时,返回函数(返回的是if语句而不是函数吗?)我想知道何时执行picked.pop()

如果我有任何误解,请寻求指导。

代码

def pick(n, picked, to_pick):
    if to_pick is 0:
        return print(picked)

    if len(picked) is 0:
        smallest = 0
    else:
        smallest = picked[-1] + 1

    for next in range(smallest, n):
        picked.append(next)
        pick(n, picked, to_pick - 1)
        picked.pop()


if __name__ == '__main__':
    result = list()
    pick(7, result, 4)

1 个答案:

答案 0 :(得分:0)

想象一下:

result = []
pick(7, result, 4)

此代码的作用是在第一次调用时会将您的最小数字设置为0。因此,此时您有smallest=0, n=7, to_pick=4。从这一刻开始,您将拥有:

1-您的代码进入循环,您的空列表将附加最小值。

2-之后,该函数将被递归调用,这一次您的to_picked值减小了1。

3-您当前的最小值将是前一个最小值+ 1,然后再次转到第二行。

4-达到最终条件后,将打印列表。第一次是[0,1,2,3]。您将退出上一个递归函数,然后转到下一行。

5-这次将弹出最后一个项目。因此,您的列表将为[0,1,2]。

6-您在循环中更进一步,这次您的下一个值将是最小值+ 1,而您的最小值是3。这将被附加,因此您的列表将是[0,1,2, 4]。

编辑:所以我发现您的主要问题是,您不了解递归函数中return的工作方式。假设您有这样的非递归函数:

def foo(A):
   return A
def bar(B):
   result = foo(B)
   return result

函数bar完成工作后,在函数foo中,它将返回到上一个作用域,即函数bar的作用域,下一行将被执行。是return result

递归函数的逻辑相同,不同之处在于您一次又一次地调用同一函数。达到最终条件后,您将返回到先前的范围,直到再次达到最终条件为止。而且此操作将重复进行,直到您达到所有可能的最终条件。

因此,在您的情况下,第一次达到最终条件时将具有:

n=7, picked = [0,1,2], smallest = 2, n = 1

从最终条件返回后,选择的数组将为[0,1,2,3],代码将执行下一行。将会是picked.pop()。因此,您将再次以picked = [0,1,2]结尾,但是这次您已到达循环的最后一行。

因此,下一次您的next值将由smallest + 14更新,这将再次重复直到循环结束。并且您将再次以[0,1,2]结尾。

循环结束后,您的函数将返回上一个作用域。这次将弹出[0,1,2],您将得到[0,1],然后重复该过程。