在我的最后一个任务中,我得到了停靠点,因为在没有必要的情况下使用递归。在你不需要的地方使用递归是不好的做法吗?
例如,这个Python代码块可以用两种方式编写:
def test():
if(foo() == 'success!'):
print(True)
else:
test()
或
def test():
while(True):
if(foo() == 'success!'):
print(True)
break
一个天生就好比另一个好吗? (表现方面还是实践方式)?
答案 0 :(得分:5)
虽然递归可能允许更容易阅读的解决方案,但是存在成本。每个函数调用都需要少量的内存开销和循环迭代不需要的设置时间。
默认情况下,Python调用堆栈也限制为1000个嵌套调用;每个递归调用都会计入该限制,因此您可能会冒任何递归算法引发运行时错误。循环可能产生的迭代次数没有这么严格的限制。
答案 1 :(得分:4)
他们不一样。迭代版本理论上可以永远运行,一旦输入它就不会改变Python虚拟机的状态。然而,递归版本在继续运行时不断扩展调用堆栈。正如@chepner在他的回答中提到的那样,你能保持多长时间是有限的。
对于您提供的示例,您很快就会注意到这种差异!由于foo
永远不会改变,当foo !='success!'
递归版本一旦你炸掉堆栈就会引发异常(这不会花费很长时间),但是迭代版本会#34;挂起&#34 34 ;.对于实际终止的其他函数,在同一算法的两个实现之间,一个是递归的,另一个是迭代的,迭代版本通常会优于递归版本,因为函数调用会产生一些开销。
通常,递归应该是最低限度的 - 通常有一个最简单的情况,它们可以完全处理而无需进一步的递归调用(n = 0,列表或元组或dict是空的等等)对于更复杂的输入,递归调用工作在输入的组成部分(列表的元素,字典的项目,......),返回其子问题的解决方案,调用实例以某种方式组合并返回。
递归与数学归纳类似,并且在很多方面都与数学归纳相关 - 更常见的是,有充分根据的归纳法。你推理使用归纳的递归过程的正确性,因为递归传递的参数通常是#34;较小的"而不是传递给来电者的那些。
在你的例子中,递归是没有意义的:你没有将数据传递给嵌套的调用,它不是分而治之的情况,根本就没有基本情况。这是"无限" /无界循环的错误机制。