如何使用递归获取数字列表的总和?

12
我想使用递归函数来求和,例如:
getSum([1, 2, 3, 4, 5]) 

应该返回1+2+3+4+5 == 15

我不是递归函数的专家,我尝试了一些类似于:

def getSum(piece):
    for i in piece
        suc += getSum(i)

问题在于我无法循环整数。我相信这是一个非常简单的任务,但我真的想不出来。
8个回答

19

您不需要使用循环。递归会为您完成这个工作。

def getSum(piece):
    if len(piece)==0:
        return 0
    else:
        return piece[0] + getSum(piece[1:]) 
print getSum([1, 3, 4, 2, 5])

如果我想在每次调用 getSum 函数后检查总和怎么办?所以我想检查例如,如果总和大于9:做某事? - H. Hasin

8

我认为不需要显式地检查长度会更好:

def getSum(piece):
    return piece[0] + getSum(piece[1:]) if piece else 0

示例:

>>> getSum([1, 2, 3, 4, 5])
15

3

为了学习Python(学术目的),您可以使用递归:

def getSum(iterable):
    if not iterable:
        return 0  # End of recursion
    else:
        return iterable[0] + getSum(iterable[1:])  # Recursion step

但是在实际的生产代码中,不应该使用递归。这样不仅效率低下,而且代码不如使用内置函数清晰明了。对于这种情况,既不需要递归也不需要循环。只需使用内置函数sum

>>>a = [1, 2, 3, 4, 5]
>>>sum(a) 
15

1
但是我必须使用递归来完成它 :P - H. Hasin
不要在生产代码中使用递归。在学术目的上可能可以,但在实际生活中不要这样做。 - The Godfather
uselpa,谢谢,已修复。 - The Godfather

2

你也可以使用reduce。

函数reduce(func, seq)将函数func()连续应用于序列seq。它返回一个单一的值。

reduce(lambda x,y: x+y, range(1,6))

1
如果你的列表比简单列表更复杂,例如:
mylist = [1,-10,[[2,[3]],7.3],[[[[[[[[[-5]]]],2]]],1],4]]

你应该使用以下代码:

mylist = [1,-10,[[2,[3]],7.3],[[[[[[[[[-5]]]],2]]],1],4]]

def getSum(piece):
    if len(piece)==0:
        return 0
    elif type(piece[0]) is list:
        return getSum(piece[0]) + getSum(piece[1:])
    else:
        return piece[0] + getSum(piece[1:]) 
        
print(getSum(mylist))

0

或者,更符合Python风格的方式:

suml = lambda l: l[0] + suml(l[1:]) if l else 0

print(suml(range(101)))

输出:5050


0

使用递归和弹出函数

def getSum(piece):
    return piece.pop() + getSum(piece) if piece else 0

0

像这样的东西:

def rec_sum(array):
  total = 0
  if len(array):
    total += array.pop(0) + rec_sum(array)
  return total

看起来还行。但要注意,每次我们从开头弹出一个元素时,这将导致整个列表移动一位。使用array.pop()只弹出最后一个元素可能更好。当然,递归本身是不必要的,但是楼主要求这样做。 - juanpethes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接