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