Python3 学习笔记14_递归函数_20180305
2018-03-05 17:03
357 查看
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # 学习网站:www.liaoxuefeng.com #**************************************************** # Python3 函数 * #**************************************************** print ("--------------------分割线------------------") #============ # 递归函数 #============ # 递归函数:直接或间接的调用函数自身。 # 阶乘 n! = 1*2*3*4*...*n def fact1(n): if n == 1: return 1 return n * fact1(n - 1) print( fact1(3) ) # 6 ''' ===> fact(3) ===> 3 * fact(2) ===> 3 * (2 * fact(1)) ===> 3 * (2 * 1) ===> 3 * 2 ===> 6 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种 数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回 栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多 就会导致栈溢出。 ''' # print( fact1(1000) ) # 报错:maximum recursion depth exceeded in comparison print ("--------------------分割线------------------") ''' 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是 一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含 表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调 用多少次,都只占用一个栈帧,不会出现栈溢出的情况。 上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就 不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的 乘积传入到递归函数中 ''' def fact2(n): return fact_iter(n, 1) def fact_iter(num, product): if num == 1: return product return fact_iter(num-1, num*product) print( fact2(3) ) # 6 ''' 可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身, num - 1和num * product在函数调用前就会被计算,不影响函数调用。 fact2(3)对应的fact_iter(3, 1)的调用如下: ===> fact_iter(3, 1) ===> fact_iter(2, 3) ===> fact_iter(1, 6) ===> 6 尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导 致栈溢出。 遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优 化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。 小结: 使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。 针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是 等价的,没有循环语句的编程语言只能通过尾递归实现循环。 Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。 '''
相关文章推荐
- 【Python学习笔记】递归函数
- 【深度学习】笔记14 windows下caffe的python接口的配置(数据的可视化环境)
- 【python学习笔记】14:开发一个简易的爬虫
- 用python-pygame画出来sin函数曲线-学习笔记14
- 廖雪峰python学习笔记14.多进程和多线程
- python学习笔记14 list列表数组
- python学习笔记 递归函数
- python 学习笔记14-----图像用户界面开发
- python学习笔记-(14)python循环中的高级用法
- 32位汇编语言学习笔记(14)--递归函数的调用
- Python学习笔记(14) -- Python IDLE或shell中切换路径
- 学习笔记14-python list
- Python学习笔记010——递归函数
- python学习笔记14(多态、封装、继承)
- Python学习笔记14
- Python学习笔记14:Python执行环境
- Python学习笔记14:标准库之信号量(signal包)
- Python3 学习笔记13_函数的参数_20180305
- python学习笔记(14)--爬虫下载漫画图片修改版
- Python 学习笔记 - 14.技巧(Tips)