为什么这种递归方式和它意味着什么?

时间:2016-04-26 07:39:40

标签: python

我试图理解这段代码

def listSum(ls):
    if not ls:
        return 0

    return ls[0] + listSum(ls[1:])

有两件事让我有点烦恼

  1. if not ls: - 这是什么意思?由于没有指定任何内容,它在寻找什么?
  2. ls[0] + listSum(ls[1:]) - 我已尝试仅使用listSum(ls[0:])而且我遇到了运行错误。为什么?我为什么要坚持ls[0] + listSum(ls[1:])

1 个答案:

答案 0 :(得分:4)

想象一下它被称为......

listSum([3, 5, 3, 7])

归结为......

return ls[0] + listSum(ls[1:])

...评估为......

return 3 + listSum([5, 3, 7])

然后listSum([5, 3, 7])5 + listsum([3, 7])

然后listSum([3, 7])3 + listsum([7])

然后listSum([7])7 + listsum([]),这是not ls开始并返回0的位置。

所以,然后将完整的东西评估为......

3 + 5 + 3 + 7 + 0

注意:

  • listSum(ls[1:])每次缩短列表 - 减少剩余问题的复杂性,直到调用listSum收到空列表:if not ls: return 0处理的简单案例

  • 递归解决方案通常由两部分组成:最简单可能输入的解决方案(或者有时是一些非常简单的情况),以及如何处理任意复杂输入并将其减少为公式的内容进行一次或多次重复调用,每次调用至少要简单一些,总是朝着最简单的输入方向发展

  • “我尝试过使用listSum(ls[0:]) - ls[0:]会返回ls的副本 - 它会要求提供相同的列表无限制地处理

  • 明确处理一个元素的列表可能更直观 - if len(ls) == 1: return ls[0] - 但如果有人调用listSum([]),您会尝试访问[0](在另一个代码低于if)并引发异常;处理空列表使函数更容易使用如果 listSum([])返回0对您的应用程序是理智的,但另一方面listSum([])引发异常可能发现列表意外为空的错误 - 您可以决定哪个对您更有用;幸运的是,如果你处理空列表情况,len(ls) == 1情况然后“正常工作”与相同的递归逻辑