喜欢一个人需要理由吗?需要吗?不需要吗?需要吗?不需要吗?这是个鬼知道天晓得的事情。本来你什么也不在乎,开开心心的、吃着火锅、坐着火车、唱着歌出了城......忽然间火车被人掀翻到水里了,你从水里钻了出来,睁眼看见一个细腰长腿一头长发的女土匪,一脚踩在你的脸上,威风凛凛,说此山是我开此树是我栽要想打此过留下买路财,若敢说个不字管杀不管埋!你心里一动,恨不得留下来和她一起当土匪......那个瞬间你就喜欢上她了呗。
递归定义
递归函数:这个函数在他的内部调用了自身。函数自己调用自己,实现递归。
递归特性:
- 记住所有的递归函数都有一个退出条件
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
普通算法实现高斯求和:
def sum(munber):
total=0
for i in range(1,munber+1):
total+=i
return total
print sum(100)
运行结果:
5050
如果使用递归方法:
def sum_number(number):
if number==0:
return False
return sum_number(number-1)+number
# 第一次是sum_number(99)+100的值
# 第二次是sum_number(98)+99的值
# 最后一个是sum_number(0)
print sum_number(100)
运行结果:
5050
引申下一个面试题:
res = [lambda x:x+i for i in range(10)]
print res[0](10)
运行结果:
19
解释:
res其实就是[lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i,lambda x:x+i]的列表。
res[0]就是取列表的第一个元素,就是–>lambda x:x+i(10)。匿名函数传递参数10,传递给参数x,i的值就是最上面定义的for i in range(10)。
函数在调用的时候才去查找变量,res[0]相当于lambda x:x+i,要求中res[0](10)的10就是传入x的值。i的值在遍历最后的值是9,所以引用i的值就是9。
递归小坑
在写百度子域名采集的时候,因为百度经常会返回一些失败的页面,所以需要对访问百度的函数进行递归操作,直到返回正确的页面。但是发现在递归函数得到正确页面,返回的结果却是None,找了一下资料,才明白递归的本质原理是酱紫的:
主要的原因是函数调用中的堆栈进出顺序,比如:
运行递归函数1
函数1不是想要的结果...
运行递归函数2
函数2不是想要的结果....
运行递归函数3
递归函数3是想要的结果...
准备返回函数3的结果
函数3的结果返回到函数2
函数2没有想要的结果....
返回None
解决方法是返回递归函数的返回结果
即在函数1不是想要的结果.....
执行函数2的时候.....
返回函数1
用代码写出来就是
def test(x):
if x<10:
x+=1
test(x)
else:
return x
改成
def test(x):
if x<10:
x+=1
return test(x)
else:
return x