Python进阶 —— 尾递归

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python进阶 —— 尾递归相关的知识,希望对你有一定的参考价值。

参考技术A

下面是笔者的个人理解: 把计算出的值存在函数内部(当然不止尾递归)是其计算方法,从而不用在栈中去创建一个新的,这样就大大节省了空间。函数调用中最后返回的结果是单纯的递归函数调用(或返回结果)就是尾递归。

实例还是和笔者的上一篇文章相同,建议读者阅读 Python —— 递归

常规递归阶乘:

我们来看一下执行过程:

但是如果把上面的函数写成如下形式:

我们再看下执行过程:

很直观的就可以看出,这次的 factorial 函数在递归调用的时候不会产生一系列逐渐增多的中间变量了,而是将状态保存在 acc 这个变量中。而这种形式的递归,就叫做尾递归。

常规递斐波那契数列:

而尾递归:

一下子就充满了逼格,还高效了许多,何乐而不为呢!

尾递归,

总所周知,尾递归是一种特殊的递归;因为这一次递归返回的下一次的结果,所以避免了递归栈,对于空间上来讲是一种节省。

所有的递归都有非递归来书写,尾递归也可以达到和非递归相同的结果。

但是python是不支持尾递归的,因为要返回错误栈和错误类型。

 

 

python 默认的递归栈大小可以通过以下获得

sys.getrecursionlimit()

python 可以设置递归栈的大小

sys.setrecursionlimit()

 

 

但是今天的我大开眼界。

https://www.cnblogs.com/Alexander-Lee/archive/2010/09/16/1827587.html

import sys  
  
class TailRecurseException:  
  def __init__(self, args, kwargs):  
    self.args = args  
    self.kwargs = kwargs  
  
def tail_call_optimized(g):  
  """  
  This function decorates a function with tail call  
  optimization. It does this by throwing an exception  
  if it is it‘s own grandparent, and catching such  
  exceptions to fake the tail call optimization.  
    
  This function fails if the decorated  
  function recurses in a non-tail context.  
  """  
  def func(*args, **kwargs):  
    f = sys._getframe()  
    if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code:  
      raise TailRecurseException(args, kwargs)  
    else:  
      while 1:  
        try:  
          return g(*args, **kwargs)  
        except TailRecurseException, e:  
          args = e.args  
          kwargs = e.kwargs  
  func.__doc__ = g.__doc__  
  return func  

大意是通过不断的捕获错误规避了递归栈。6的一批,大开眼界。

以上是关于Python进阶 —— 尾递归的主要内容,如果未能解决你的问题,请参考以下文章

python进阶练习之——递归求阶乘

python 函数的进阶

Python 函数进阶-递归函数

python大法好——递归内置函数函数进阶

六. python进阶(递归)

Python进阶内容--- 函数式编程