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
对于初学者来说永远都不会是真的。顺便说一句,如果您试图学习递归,您可能也想尝试构建一个递归列表结构:acons(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:])