递归函数
Posted spencerzhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归函数相关的知识,希望对你有一定的参考价值。
一、递归函数
函数在调用阶段直接或间接的又调用自身
递归的次数是有限的,用sys模块来计算调用次数,是不精确的。
1 import sys 2 print(sys.getrecursionlimit())
我们可以用函数来精确算出,递归限制的次数。
1 def func(n): 2 print(‘from func‘,n) 3 func(n+1) 4 func(0)
虽然说我们可以通过setrecursionlimit来设定递归限制的次数,但是一个函数不应该无限制的递归下去!
递归分为两个阶段:
1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都应该下降。
2.递推:一次次往回推导的过程。
使用例子:
1,计算年龄,一共有五位同学,已知第一位同学的年龄是18,但是其他四位的同学的年龄未知,但是第二位同学说我比第一位大2岁,第三位同学说我比第二位大2岁,第四位同学说我比第三位大2岁,第五位同学说我比第四位大2岁,请问,第五位同学年龄是多少?
1 def age(n): 2 if n == 1: 3 return 18 4 return age(n-1)+2 5 res = age(5) 6 print(res)
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]]将列表中的数字依次打印出来
1 def get_num(l): 2 for i in l: 3 if type(i) is int: 4 print(i) 5 else: 6 get_num(i) 7 get_num(l)
二、算法之二分法
算法:解决问题的高效率方法
同样还是做一道题,给出一个列表l = [1,3,5,12,57,89,101,123,146,167,179,189,345],我们要找到一个我们要找的数,如果只是用普通的for循环查找的话,其实效率会比较低,这里我们就要用一个简单的算法,二分法:
1 l = [1,3,5,12,57,89,101,123,146,167,179,189,345] 2 3 def get_num(l,target_num): 4 if not l: 5 print(‘r u kidding me?‘) 6 return 7 middle_num = len(l)//2 8 if target_num > l[middle_num]: 9 right_list = l[middle_num+1:] 10 get_num(right_list,target_num) 11 elif target_num < l[middle_num]: 12 left_list = l[0:middle_num] 13 get_num(left_list, target_num) 14 else: 15 print(‘find it!‘) 16 get_num(l,target_num)
三、三元表达式
def my_max(x,y): if x > y: return x return y
基于之前的知识,我们只能这么比较两个数的大小,但是用三元表达式,用一行代码就可完成功能:
res = x if x > y else y
如果if后面的条件成立,那么返回if之前的值,否则返回else后面的值
三元表达式固定表达式:
值1 if 条件 else 值2
条件成立 值1
条件不成立 值2
PS:三元表达式的应用只推荐只有两种的情况的可能下
1 username = input(‘username>>>:‘) 2 res = ‘nb‘ if username == ‘zzj‘ else ‘five‘ 3 print(res)
四、列表生成式
我现在有这么一个列表: l = [‘tank‘,‘nick‘,‘jason‘,‘kevin‘],我现在要在列表的每个元素后面加一个“sb”,那么我们是不是,可以创建一个空列表,用for循环出l中的元素,再依次加上后缀“sb”,再放入空列表中。那现在我们利用列表生成时就可以更方便的实现了。
1 l = [‘tank‘,‘nick‘,‘jason‘,‘kevin‘] 2 #列表生成式 3 res = [‘%s_sb‘%name for name in l ] 4 print(res)
基于上面得到的列表,我们得到了:l = [‘tank_sb‘, ‘nick_sb‘, ‘jason_sb‘, ‘kevin_sb‘],但是如果这个列表中加入了一个新的元素‘zzj_nb’,变成了l = [‘tank_sb‘, ‘nick_sb‘, ‘jason_sb‘, ‘kevin_sb‘,‘zzj_nb‘],那么就可以用一个新功能。
res = [name for name in l if name.endswith(‘_sb‘)]
print(res)
那么这个方法对于字典同样有效
1 l1 = [‘name‘,‘password‘,‘hobby‘] 2 l2 = [‘jason‘,‘123‘,‘DBJ‘] 3 d = j:l2[i] for i,j in enumerate(l1) 4 print(d)
不仅对于字典,元组集合同样有效,但是要注意的是,元组出来的是一个迭代器。只有当你从中取得时候,才会返回给你。
五、匿名函数
匿名函数:没有名字的函数
匿名函数的特点:临时存在,用完就没了
res = (lambda x,y:x+y)(1,2) print(res)
左边的就相当于函数的形参,右边的就相当于函数的返回值
匿名函数一般不会单独使用,它是用来配合内置函数一起使用。
六、常用的内置函数
1.max
1 d = 2 ‘egon‘:30000, 3 ‘jason‘:88888888888, 4 ‘nick‘:3000, 5 ‘tank‘:1000 6 7 8 print(max(d,key = lambda name:d[name]))
2.map映射
1 l = [1,2,3,4,5,6] 2 print(list(map(lambda x:x+2,l)))
3.zip拉链
1 l1 = [1,2,3] 2 l2 = [‘zzj‘,‘zzp‘,‘lzx‘] 3 print(list(zip(l1,l2)))
得出的结果是以元组的形式
4.filter 过滤
1 l = [1,2,3,4,5,6] 2 print(list(filter(lambda x:x != 4,l)))
5.sorted 排序
1 l = [2,3,5,1,4,7,0] 2 print(sorted(l))
6.reduce
1 l = [2,3,5,1,4,7,10] 2 from functools import reduce 3 print(reduce(lambda x,y:x+y,l,19))# 19 初始值
当初始值不存在的情况下,就从列表中获取第一个元组,与第二个元素进行两两相加,之后每获取一个就与上一次结果再相加。
以上是关于递归函数的主要内容,如果未能解决你的问题,请参考以下文章