python 之 递归
终于来到了这里,这是一座山,山那边都是神仙
定义:在一个函数里调用函数本身
最好的例子就是,求阶乘
def factorial(n): if n == 1: return 1 elif n > 1: return n*factorial(n-1) while True: n = input('n>>') n = int(n) print(factorial(n))
递归最大层数
上面金典的例子运行的很成功
下面再来一个,是一个古老的故事,说,从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢?
我们用代码开实现一下
def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) while True: story()
你运行了吗?
shit,他报错了,但是这个故事讲的很完美。
RecursionError: maximum recursion depth exceeded while calling a Python object
这个错误是说,这个程序运行的代码,超过了最大递归层数。
正如我们看到的,如果没有外界阻力,它会一直运行下去
# 添加参数,设置停止条件 def calc(n, count): print(n, count) if count < 5: return calc(n/2, count+1) else: return n print(calc(188,0))
因为每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,直到内存被占满,然后死机。
所以限制了他的最大递归层数,一般就是999层,
当然这个数字是可以修改的,修改方法很冷门,一般也不会有人去修改它,
因为如果递归了999层都没有解决问题,那么,你该想想是不是代码写的太烂了,呵呵……..
递归的特性
1、递归必须要有一个结束条件,否则就是一个死循环,直到报错
2、每次进入更深一次递归时,递归的规模会比上次递归有所减小
3、递归的执行效率不高,递归层次过多会导致栈溢出
递归的作用
用于很多计算:斐波拉契数列,汉罗塔,多级评论树,二分查找,阶乘
二分查找例子
data_set = [1,3,4,6,7,8,9,10,11,13,14,16,18,19,21] # data_set = list(range(101)) def b_search(n, low, high, d): mid = int((low + high) / 2) # 中间值 print(mid) if low == high: # 第一位 和 最后一个 对比(索引的对比) print('not find') return if d[mid] > n: print('go left', low, high, d[mid]) b_search(n, low, mid, d) if d[mid] < n: print('go right', low, high, d[mid]) b_search(n, mid, high, d) else: print('find it', d[mid]) b_search(16, 0, len(data_set), data_set)
尾递归
尾递归是对递归的优化,提高递归的效率,但是在python中并不支持,然并卵
优化:
在调用下次递归时,直接return自己,不保留外层函数的在内存中的数据,递归需要的只是这一层的信息,所以节省了内存,提高了效率
然而在python中,因为没有优化,我们鼓励使用迭代器来改写尾递归
(引用自知乎)