Python 如何使用递归获得列表中所有元素的总和

Python 如何使用递归获得列表中所有元素的总和,python,list,recursion,Python,List,Recursion,有人能告诉我为什么它不起作用吗?任何帮助都将不胜感激。您应该: def sumAll(lis): return 0 if isEmpty(lis)== True\ else head(lis)+sumAll(tail(lis)) def isEmpty(lis): return True if lis==0 else False def head(lis): return lis[0] def tail(lis): return lis[1:] a

有人能告诉我为什么它不起作用吗?任何帮助都将不胜感激。

您应该:

def sumAll(lis):
    return 0 if isEmpty(lis)== True\
    else head(lis)+sumAll(tail(lis))

def isEmpty(lis):
    return True if lis==0 else False

def head(lis):
    return lis[0]

def tail(lis):
    return lis[1:]

a=input()

print sumAll(a)
而不是:

return 0 if not lis else head(lis)+sumAll(tail(lis))
isEmpty(lis)
始终为
False
,因为:

return 0 if isEmpty(lis) else head(lis)+sumAll(tail(lis))
为什么要使用递归?我希望这只是为了练习递归

提示:始终使用调试器来真正了解程序的流程并更好地捕获错误。

如何减少错误

>>> isEmpty([])
False
使用尾部递归:

def sum(container):
    if len(container) == 1: 
        return container[0]
    if not container: 
        return 0

    val = container.pop()
    container[0] += val

    return sum(container)
Python没有针对尾部递归进行优化,因此在Python中这样做没有好处,但在其他语言中这样做可能会有好处,因为它避免了创建多余的堆栈帧,因为函数返回递归调用的结果。
函数只调用自身,直到条件为真

在代码中,所有递归调用都必须在计算最终和之前完成。 如果在中运行代码,您将看到差异

在代码更改中:

def sumAll(lis, summed = 0):
    if not lis:
        return summed
    else:
        summed += lis[0]
        return sumAll(lis[1:],summed)

In [2]: sumAll([1,2,3])
Out[2]: 6

In [3]: sumAll([1,2,3,4,5])
Out[3]: 15
lis
永远不会是
==0
,要检查空列表,如果不是lis,可以使用

def isEmpty(lis):
    return True if not lis else False # change to "not lis", which is an empty list []
您可以将自己的代码简化为:

def sum_all(lis):
    if isEmpty(lis): # same as if is_empty(lis) == True
        return 0
    else:
        return head(lis) + sum_all(tail(lis))

def is_empty(lis):
    return not lis

def head(lis):
    return lis[0]

def tail(lis):
    return lis[1:]

为什么要对递归进行此操作?是的,有一个名为
sum()
的函数,您可以将一个iterable传递给它。
lis==0
对于初学者来说永远都不会是真的。顺便说一句,如果您试图学习递归,您可能也想尝试构建一个递归列表结构:a
cons(hd,tl)
返回
(hd,tl)
,以及相关的
头部
尾部
制作列表
等功能。这样,您就可以更直接地了解从左到右折叠/附加/等的区别,以及尾巴共享等等。@MartijnPieters谢谢。或者他可以修复
isEmpty
,而不是让它坏掉而不使用它。@abarnert确实。。我认为OP现在应该能够做到这一点。@Marounnaroun:同意;在你的回答和Martijn在这里的评论以及关于另一个问题的评论之间,他应该没有问题;这已经是一个布尔值了。如果条件为假,切勿使用
;如果
condition
尚未返回布尔值,请改用
bool()
。在没有解释的情况下将程序重写为尾部递归可能对他没有帮助。你需要解释你为什么这么做(也可能提到它实际上对Python没有任何好处,但它仍然值得学习)。@abarnert,我把OP的程序完全放在原处,只是整理它并纠正错误。此外,我还解释了为什么它不起作用,实际使用了OP使用的所有函数,代码运行时返回正确的结果。@PadraicCanningham:添加一个
summared=0
参数并将其重新组织为尾部递归,这比整理和纠正错误要多得多。展示OP是一件很有用的事情,但前提是你要解释它的不同之处以及你为什么要这样做。@abarnert,我说的是我对OP代码所做的更改,我还是添加了一个解释。我想你的意思是
返回容器[0]
def sum_all(lis):
    if not lis: # same as if is_empty(lis) == True
        return 0
    else:
        return lis[0] + sum_all(lis[1:])