今日内容:
函数递归, 算法之二分法, 列表生成式, 匿名函数, 常用的内置函数
函数的递归:
定义:函数在调用阶段直接或者间接的再次调用自身
直接调用方式:
def func(): print('from func') func() func()
关于计算内存递归次数限制的补充:
import sys print(sys.getrecursionlimit()) # 1000,数据不是很精确 sys.setrecursionlimit(2000)
def func(n): print('from func',n) func(n+1) func(1) # 997
间接调用方式:
def index(): print('from index') login() def login(): print('from login') index() login()
注意点:函数不应该无限制的递归下去,需要人为结束这个过程!!!
递归算法解析(重要):
递归分为两个阶段:
- 1.回溯:一直往后问,就是一次次重复的过程,这个过程必须建立在每一次重复问题的复杂度都应该下降的前提,直到出现一个最终的结束条件即可停止
- 2.递推:一直往回推导的过程
关于出现递归思想的例题:
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
age(n) = age(n-1) + 2 # n > 1的情况
age(1) = 18 # n 指向 1
def age(n): if n == 1: return 18 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) is int: print(i) else: for item in i: if type(item) is int: print(item) else: for j in item: if type(item) is int: print(item) else: ......
# 运用递归算法解决 def get_num(l): for i in l: if type(i) is int: print(i) else: get_num(i) get_num(l) l1 = [] for i in l1: print(i)
递归函数不要考虑循环的次数,只需要把握结束的条件即可!!!
算法:
定义:解决问题的高效率的方法
二分法:
前提:容器类型里面的数字必须有大小顺序(排序)!!!
l = [1,3,5,7,9,11,22,34,45,57,67,88,99,111]
target_num = 34
def get_num(l,taeget_num):
if not l:
print('操作失败')
return
print(l)
# '获取列表中间的索引
middle_index = len(l)//2
# 判断target_num跟middle_inden对应的数字的大小
if target_num > l[middle_index]:
# 切取列表右半部分
num_right = l[middle_index + 1:]
# 再递归调用get_num函数
get_num(num_right,target_num)
elif target_num < l[middle_index]:
# 切取列表左半部分
num_left = l[0:middle_index]
# 再递归调用get_num函数
get_num(num_left,target_num)
else:
print('find it',target_num)
get_num(l,target_num)
三元表达式:
定义:当某个条件成立时,做一件事;不成立时,做另外一件事
# 模板 x = 1 y = 2 res = x if x > y else y # 若果if后面的条件成立,就返回if前面的值;否则返回else后面的值 print(res)
三元表达式固定表达式
值1 if 条件 else 值2
条件成立时返回 值1
条件不成立时返回 值2
前提 :三元表达式的应用场景,只推荐在只有两种情况的可能下
# 进阶应用 is_free = input('请输入是否面(y/n)>>>:') if_free = '免费' if is_free == 'y' else '收费' print(is_free)
列表生成式:
用常规方式解决的例题:
l = ['tank','nick','oscar','soan'] l1 = [] for name in l: li.append('%s_sb'%name) print(l1) # ['tank_sb','nick_sb','oscar_sb','soan_sb']
使用列表生成式解决上一例题:
l = ['tank','nick','oscar','soan'] res = ['%s_sb'%name ofr name in l] print(res) # ['tank_sb','nick_sb','oscar_sb','soan_sb']
['tank_sb','nick_sb','oscar_sb','soan_sb','jason']
将列表中带_sb的人名取出:
res = [name for name in l if name.endswith('_sb')] # 先for循环依次取出列表中的每一个元素,然后交由if判断,如果条件成立,才会交给for前面的代码;
# 如果条件不成立,则当前的元素直接舍弃,且后面不支持再加else的情况 print(res)
字典生成式:
用常规方式解决的例题:
# 简单的枚举出key值,默认用的是数字编号,并没有返回出字典
l1 = ['name','password','hobby'] l2 = ['jason','123','DBJ'] for i,j in enumrate(l1): print(i,j) ''' 0 name 1 password 2 hobby '''
# 同样运用枚举,创建空字典,令l1的key = l2的value形成新字典 l1 = ['name','password','hobby'] l2 = ['jason','123','DBJ'] d = {} for i,j in enumrate(l1): d[j] = l2[i] print(d) # {'name':'jason','password':'123','hobby':'DBJ'}
用字典生成式解决上一例题:
l = ['jason','123','read'] d = {i:j for i,j in enumrate(l)} print(d) # 生成字典{0:'jason',1:'123',2:'read'} d = {i:j for i,j in enumrate(l) if j != '123'} print(d) # {0:'jason',2:'read'} 因为有 j != '123' 的条件
匿名函数:
定义:没有名字的函数
匿名函数的特点: 临时存在,且用完就没了
# 例子:my_sum就能使x + y def my_sum(x,y): return x + y
# 使用匿名函数:lambda
res = (lambda x,y:x+y)(1,2) print(res) func = lambda x,y:x+y print(func(1,2)) ''' : 左边的相当于函数的形参 : 右边的相当于函数的返回值 '''
匿名函数通常不会单独使用,而是配合内置函数一起使用
常用的内置函数:
map zip filter sorted reduce
l = [1,2,3,4,5] print(max(l)) # 这样print,会使它的内部是基于for循环的
# 进阶理解 d = { 'egon':30000, 'jason':88888888, 'nick':3000, 'tank':1000 } def index(name): return d[name] print(max(d,key=index)) # 比较薪资,返回人名
# 同样的例题,我们这次使用匿名函数: d = { 'egon':30000, 'jason':88888888, 'nick':3000, 'tank':1000 } print(max(d,key=lambda name:d[name])) # 比较薪资,返回人名
map :映射(基于for循环)
l = [1,2,3,4,5] print(list(map(lambda x:x+1,l))) # 基于for循环的方式返回出[2,3,4,5,6]的结果
zip :拉链(3个及以上对象也可以运用,基于for循环的)
l1 = [1,2,3] l2 = ['jason','egon','tank'] print(list(zip(l1,l2))) # [(1,'jason'),(2,'egon'),(3,'tank')]
filter :(基于for循环的)
l = [1,2,3,4,5,6] print(list(filter(lambda x:x!=3,l))) # [1,2,4,5,6]
sorted :排序
l = ['jason','egon',nick','tank'] print(sorted(l,reverse=True)) # ['tank','nick','jason','egon']
reduce (重要):
from functools import reduce l = [1,2,3,4,5,6] print(reduce(lambda x,y:x+y,l)) # 当初始值不存在时,首次获取两个元素相加,之后每次获取一个与上一次相加的结果再相加 from functools import reduce l = [1,2,3,4,5,6] print(reduce(lambda x,y:x+y,l,19)) # 这里情况为初始值存在且19是初始值,也就是第一个参数