在列表中添加元素和计数元素时的PYTHON RECURSION行为

时间:2018-08-15 16:48:09

标签: python python-3.x

我最近研究了Python递归。我发现有些事情很难理解。

看起来像在python中通过递归计数和添加列表的元素几乎以类似的方式完成。有人可以解释一下为什么这些调用只是在下面的返回调用中加上“ 1”和“ num [0]”而导致其行为有所不同的原因:  return "*1*"+sum(num[1:])return "*num[0]*"+sum(num[1:])

列表中数字计数的代码:

def count(num):
    if len(num) == 0:
        return 0
    return 1+count(num[1:])

print(count([1,2,3,4,5,6,11]))  

输出:7

在列表中添加元素的代码:

def sum(num):
    if len(num) == 0:
        return 0
    return num[0]+sum(num[1:])

print(sum([1,2,3,4,5,6,11]))

输出:32

有人可以在上述两个递归程序中解释返回声明吗?

任何对我有意义的信息都会有很大的帮助。非常感谢。

1 个答案:

答案 0 :(得分:2)

首先,让我们用一个循环来编写它,它更具Python风格,对于新手来说也可能更容易理解:

def count(nums):
    res = 0
    for num in nums:
        res = 1 + res
    return res

def sum(nums):
    res = 0
    for num in nums:
        res = num + res
    return res

+操作中相同的一个单词。但是现在,希望您能理解为什么会有所不同。第一个从0开始,然后向每个元素加1。第二个元素以0开头,并将元素添加到该元素,每个元素添加一次。


除了稍微复杂一点之外,递归代码基本上在做同样的事情。

实际上,将每个元素压入堆栈,然后从0开始,然后将堆栈弹出直到其为空,然后为每个元素分别添加1或元素(从堆栈弹出)。 1

但是将一堆元素压入堆栈并弹出它们会得到相同的元素,只是相反。将每个元素加1或将所有元素加起来,就可以实现向后计数与向前计数相同的功能。


如果您仍然不明白,则应尝试逐步完成通话。通常,我建议使用交互式可视化工具,例如Python Tutor,但是由于此问题似乎是专门为使您从功能上进行思考而设计的,因此我们就可以这样做。

想象一下,Python中的函数调用只是用参数替换参数的问题。 2

所以:

count([1,2,3])
= 0 if len([1,2,3]) == 0 else 1 + count([2,3])
= 1 + count([2,3])
= 1 + (0 if len([2,3]) == 0 else 1 + count([3]))
= 1 + (1 + count([3]))
= 1 + (1 + (0 if len([3]) == 0 else 1 + count([])))
= 1 + (1 + (1 + count([])))
= 1 + (1 + (1 + (0 if len([]) == 0 else 1 + count([])))))
= 1 + (1 + (1 + (0)))
= 1 + (1 + (1))
= 1 + (2)
= 3

sum([5,10,1])
= 0 if len([5,10,1]) == 0 else 5 + count([10,1])
= 5 + count([10,1])
= 5 + (0 if len([10,1]) == 0 else 10 + count([1]))
= 5 + (10 + count([3]))
= 5 + (10 + (0 if len([3]) == 0 else 1 + count([])))
= 5 + (10 + (1 + count([])))
= 5 + (10 + (1 + (0 if len([]) == 0 else ??? + count([])))))
= 5 + (10 + (1 + (0)))
= 5 + (10 + (1))
= 5 + (11)
= 16

此外,请注意上面的???num[0]为空时num是什么?那会引发一个异常,但是,因为我们从不使用该分支,所以执行该操作并不重要。


1。它也无缘无故地制作了很多无用的列表副本,只是让作者假装他是使用Scheme而不是Python进行编程,但我们忽略了这一点。

2。他们不是,但是只要您不做作业或其他任何形式的变异,您实际上就无法分辨出区别。这就是为什么喜欢纯函数式语言(在其中您无法执行任务等)的人喜欢它们的原因。