Python:递归和返回

时间:2017-07-17 05:02:53

标签: python recursion scope

作为练习,我试图制作一个脚本,它可以给我一个列表中项目的总和,但不使用SUM或FOR / WHILE循环。

我最终解决了它:

def addition(data, total=0):
    if data:
        total += data.pop()
        return total if data == [] else addition(data, total)

print(addition([1,2,3,1,2,1]))

这很有效并返回' 10'但我的初步方法是:

def addition(data, total=0):
    if data != []:
        total += data.pop()
        addition(data, total)
    return total

print(addition([1,2,3,1,2,1]))

并且第二位代码返回' 1'而不是' 10'我无法弄清楚为什么这两种方法不能做同样的事情,或者甚至在第二个例子出现的情况下也是如此。当它进入数据= []和总数= 10的最终循环时,我猜测我错过了关于变量范围如何工作的一些规则?

(如下面的答案中所解释的,它与变量范围无关,因此我更改了标题以反映问题,对于将来发生此事的任何人)

3 个答案:

答案 0 :(得分:3)

在子函数中调用total += data.pop()时,调用函数中的变量total不会更改,因为整数是不可变的。

在函数返回之前,只有要弹出的第一个元素1被添加到total。要使其执行相同操作,您可能希望将addition(data, total)替换为return addition(data, total)

答案 1 :(得分:2)

结果与变量范围无关。您的第一个实现将递归调用的结果返回给total。第二种实现没有。因此,def addition(data, total=0): if data != []: total += data.pop() # addition(data, total) # return value not used; this line does not modify result return total # total = 0 + first element 在第一个元素之后不会更新。

pop

原始列表中的两个函数def addition(data, total=0): if data: return addition(data[1:], total + data[0]) return total 因此修改输入数据。考虑这样的替代方案:

window.onscroll

答案 2 :(得分:2)

如有疑问,请始终添加打印语句;)

def addition(data, total=0):
   if data!= []:
      total += data.pop()
      print("Total is " + str(total))
      addition(data, total)
   return total 

addition([1,2,3])返回:

Total is 3
Total is 5
Total is 6
3

你看到现在的错误在哪里吗? :)你没有对addition(data, total)的返回值做任何事情 - 这段代码没有任何结果。你可以做的是返回这个值:

def addition(data, total=0):
    if data!= []:
        total += data.pop()
        return addition(data, total) 
    return total 

让我们分析一下这段代码的作用:如果data为空 - 返回total - 我们已经添加了所有内容,无需执行任何操作。如果data不是空列表,它将从数据中弹出一个元素,将此值添加到total并使用较短的列表重复该过程。说服自己这个代码确实是你想要的。