函数递归,匿名函数
一.函数递归
递归函数:
函数在调用阶段又直接或间接的调用自身,不能无限的递归下去
递归分两个阶段:
回溯:就是一次次重复的过程,这个重复过程必须建立在复杂程度递减的情况下,直到有一个最终的结束条件
递推:一次次往回推导的过程
递归函数不需要考虑循环次数,但必须要有结束条件(*****)
import sys # 操作软件模块 print(sys.getrecursionlimit()) # 查询递归深度,不精准 998个左右 sys.getrecursionlimit(2000) # 修改递归深度
# 直接调用递归函数: def func(n): print('from func ',n) func(n+1) func(1) #间接调用递归函数 def outter(): print('form outter') inner() def inner(): print('form inner') outter() inner()
#递归函数 def age(n): if n == 1: return 10 # 结束递归回溯的条件 return age(n-1) + 2 # 递推 res = age(5) print(res)
应用
将列表中的数字依次打印出来
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]] # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点) # for i in l: # if type(i) == int: # print(i) # else: # for j in i: # if type(j) == int: # print(j) # else: # for j in j: # if type(j) == int: # pass # 用for循环可以做到,但是麻烦,而且都是重复的步骤,这时可以考虑用函数递归代替重复的代码 def get_list(list): for i in list: # for循环传入的列表 if type(i) == int: # 当i的类型是整形,则打印,否则传给函数再次运行 print(i) else: get_list(i) get_list(l)
二.二分法算法
算法:解决问题的高校的方法
二分法:只适合用在有大小顺序的容器类型数据里
用法:先与容器中间的元素进行对比,若大于中间元素,则将容器从中间切分,留取后半部分,
再与后半部分容器中间的元素进行对比,若大于,则再将后半部分容器切分,以此类推...
#判断num 是否在 l 里 l = [1,2,3,4,5,6,7,8,9] num = 7 #方法一:for循环一个个去除列表里的数与num对比,若相等则存在,若不等则不存在 for i in l: if i == num: print('find it') # 因为此方法需要把列表里的数从头一个个拿出进行对比,所以效率相对较低 #二分法: def judge(list,num): if not list: # 列表为空时,不在列表中 print('not find') return # 列表为空结束函数 middle = len(list) // 2 # 列表中间的索引 if num > list[middle]: # 如果大于列表中间的数,切取列表右半部分 num_r = list[middle+1:] judge(num_r,num) # 再递归调用函数,再次运行 elif num < list[middle]: # 如果小于列表中间的数,切取列表左半部分 num_l = list[0:middle] judge(num_l,num) # 再递归调用函数,再次运行 else: print('find it') # 当等于中间的数时打印 judge(l,7)
三. 三元表达式
三元表达式:
变量名 = 值1 if 条件 else 值2
条件成立:值1
条件不成立:值2
当条件成立 做某件事,条件不成立做 另一件事
应用场景推荐:只有两种的情况的可能下
def my_max(x,y): if x > y: return x return y print(my_max(5,y=7)) x = 5 y = 7 res = x if x > y else y # 若条件成立返回x 不成立返回y print(res) choice = input('请选择是否继续Y/N:').strip().lower() res = 'yes' if choice == 'y'else 'no' print(res)
四.列表生成式
表达式:res = [值 for 值 in 列表 if 条件 ]
利用for循环取出列表里的元素,
交给if 判断,当条件成立交给for 前面的代码,条件不成立当前元素直接舍弃,
#把列表里的每个元素加上'_s' #方法一 l = ['waller','wong','guo'] l_s = [] for i in l: l_s.append('%s_s'%i) # l_s.append(i + '_s') # 字符串拼接,此方法不推荐,效率极低 print(l_s) # 方法二 列表生成式: res = ['%s_s'%i for i in l] #取出 'er' 为结尾的元素 res1 = [i for i in l if i.endswith('er')] print(res1)
五.字典生成式
表达式:
dic = {i:j for i,j enumerate(l) if 条件}
l_value = ['waller','wong','guo'] l_key = ['name1','name2','name3'] dic = { } for i,j in enumerate(l_key): dic[j] = l_value[0] print(dic) # >>> {'name1': 'waller', 'name2': 'wong', 'name3': 'guo'} res = {i:j for i,j in enumerate(l_value)} print(res) # >>> {0: 'waller', 1: 'wong', 2: 'guo'} res1 = {i:j for i,j in enumerate(l_value) if j != 'wong'} print(res1) # >>> {0: 'waller', 2: 'guo'}
六.元组生成式
#元组元组生成式 res = {i for i in range(10)} print(res) # >>> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} res1 = {i for i in range(10) if i != 5} print(res1) # >>> {0, 1, 2, 3, 4, 6, 7, 8, 9}
七.匿名函数
不通过def来声明函数名字,而是通过lambda关键字来定义的函数称为匿名函数
先写lambda关键字,然后依次写匿名函数的参数,多个参数中间用逗号连接,然后是一个冒号,冒号后面写返回的表达式。
# :左边的相当于函数的形参
# :右边的相当于函数的返回值
# 匿名函数通常不会单独使用,是配合内置函数一起使用
ambda函数能接收任何数量(可以是0个)的参数,但只能返回一个表达式的值,lambda函数是一个函数对象,直接赋值给一个变量,这个变量就成了一个函数对象。
# 普通函数: def sun_func(x,y): return x + y res = sun_func(2,3) print(res) # 匿名函数: res = lambda x ,y : x + y print(res(2,3)) # 无参数 lambda_a = lambda: 100 print(lambda_a()) # 一个参数 lambda_b = lambda num: num * 10 print(lambda_b(5)) # 多个参数 lambda_c = lambda a, b, c, d: a + b + c + d print(lambda_c(1, 2, 3, 4)) # 表达式分支 lambda_d = lambda x: x if x % 2 == 0 else x + 1 print(lambda_d(6)) print(lambda_d(7)) def sub_func(a, b, func): print('a =', a) print('b =', b) print('a - b =', func(a, b)) sub_func(100, 1, lambda a, b: a - b)
常用的内置函数:
max():求最大数,内部是基于for循环的