1.如果一个函数在内部调用自身本身,这个函数就是递归函数。

例:计算 n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:

fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

def fact(n):
if n==1:
return 1
return n * fact(n - 1)

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

  使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

>>> fact(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in fact
...
File "<stdin>", line 4, in fact
RuntimeError: maximum recursion depth exceeded in comparison

  解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

  尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

def fact(n):
return fact_iter(n, 1) def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

python的递归函数的更多相关文章

  1. python基础——递归函数

    python基础——递归函数 递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用 ...

  2. Python之递归函数

    递归函数 初识递归函数 递归函数的定义:在一个函数里再调用这个函数本身 Python为了考虑保护内存占用情况,有一个递归深度的限制. 探究递归的默认最大深度: def foo(n): print(n) ...

  3. python:递归函数

    1,初识递归函数 1)什么是递归函数? 在函数中自己调用自己叫做递归函数 递归函数超过一定程度会报错.---RecursionError: maximum recursion dep th excee ...

  4. 【python】-- 递归函数、高阶函数、嵌套函数、匿名函数

    递归函数 在函数内部,可以调用其他函数.但是在一个函数在内部调用自身,这个函数被称为递归函数 def calc(n): print(n) if int(n/2) == 0: #结束符 return n ...

  5. python中递归函数

    python中的 递归函数,是指的是函数在函数内部调用自己的函数 需要满足两个条件,一,需要有一个明确的终止条件 二,需要函数自己在内部调用自己

  6. python 函数--递归函数

    一.递归函数的定义:在一个函数里面调用函数本身 python限制最大层数:998层 def foo(n): print(n) n+=1 foo(n) foo(1)

  7. 初识python: 递归函数 - 分解质因数

    分解质因数: 任何一个合数都可以写成几个质数相乘的形式.其中每个质数都是这个合数的因数,叫做这个合数的分解质因数.分解质因数只针对合数. 比如: 8 分解质因数是:2*2*2 10分解质因数是:2*5 ...

  8. python利用递归函数输出嵌套列表的每个元素

    1.先用 for 循环取. for item in l: if isinstance(item ,list): for newitem in item: print(newitem) else: pr ...

  9. what' the python之递归函数、二分算法与汉诺塔游戏

    what's the 递归? 递归函数的定义:在函数里可以再调用函数,如果这个调用的函数是函数本身,那么就形成了一个递归函数. 递归的最大深度为997,这个是程序强制定义的,997完全可以满足一般情况 ...

随机推荐

  1. MyBatis 系列五 之 关联映射

    MyBatis 系列五 之 关联映射 一对多的关联映射 一对多关联查询多表数据 1.1在MyBatis映射文件中做如下配置 <!--一对多单向的连接两表的查询--> <resultM ...

  2. idea编写的java代码,在cmd运行乱码解决方案

    1.解决方案 使用txt打开,另存为的时候选择编码为ANSI 即可.

  3. End to End Sequence Labeling via Bidirectional LSTM-CNNs-CRF论文小结

    本篇论文是卡内基梅隆大学语言技术研究所2016年  arXiv:1603.01354v5 [cs.LG] 29 May 2016 今天先理解一下这个是什么意思:        找到的相关理解:arXi ...

  4. Spring Boot:定制自己的starter

    在学习Spring Boot的过程中,接触最多的就是starter.可以认为starter是一种服务——使得使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boo ...

  5. STM32 volatile关键字

    为了提供对特殊地址的稳定访问. [C] 纯文本查看 复制代码 ? 1 2 3 int i=10; int j=i;     //1 int k=i;    //2 此时编译器对上面代码进行优化,因为在 ...

  6. devm_xxx机制

    前言 devm是内核提供的基础机制,用于方便驱动开发者所分配资源的自动回收.参考内核文档devres.txt.总的来说,就是驱动开发者只需要调用这类接口分配期望的资源,不用关心释放问题.这些资源的释放 ...

  7. python基础===requests学习笔记

    这里有一个新的学习requests网站:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html2017/11/30 Requ ...

  8. 可以高度定制的代理服务器anyproxy

    简介 anyproxy是一款可以高度定制的代理服务器,基于nodejs. 特征 支持https明文代理 支持低网速模拟 支持二次开发,可以用javascript控制代理的全部流程,搭建前端个性化调试环 ...

  9. 【bzoj4448】SCOI2015 情报传递

    树剖,可以相当于一个染色问题,以及询问先前节点的染色个数. 把第二种操作离线掉,然后用线段树模拟即可. #include<bits/stdc++.h> #define N 800010 # ...

  10. #error This file was generated by a newer version of protoc

    pattern@pattern89:/raid0/workspace/houjun/caffe-ssd$ sudo make all -j8PROTOC src/caffe/proto/caffe.p ...