二分法,三元表达式,生成式,匿名函数
算法简介
算法是什么,算法是用来解决问题的有效办法。
不是所有的算法都是很有效的,也有一些不达标的算法。
算法应用的场景有很多,比如我们日常生活中用到的一些软件都含有一些算法。
比如抖音他就可以根据我们浏览的爱好来给我们推相应的视频。这种算法统称 """推荐算法"""
AI行业也可以用到的 """成像算法"""
我们今天要说的是算法中比较简单的二分法
二分法
二分法使用的时候需要该算法查找的数据必须是有序的。 可以在某个数据集里拿到我们想要的数据值。
for循环也可以做到,但是遇到大量数据的时候 需要写很多重复代码 没有此方法简便 。
代码:
l1 = [2, 33, 55, 66, 77, 88, 123, 234, 444, 555, 666]
def get(l1, target_num):
# 递归函数需要一个结束条件
# 当列表长度等于0时,结束
if len(l1) == 0:
print('没有数据了')
# 函数体代码遇到return 自动结束
return
# 获得列表中间的索引值
middle = len(l1) // 2
# 比较目标数据值与中间索引位的数据值的大小
if target_num > l1[middle]:
# 切片操作 保留列表的右边一半,因为middle索引5 已经做过比较所以+1
right_l1 = l1[middle + 1:]
print(right_l1)
# 切片后的右边一半返回去
return get(right_l1, target_num)
# 比较目标数据值是否小于中间索引位的数据值
elif target_num < l1[middle]:
# 切片操作 保留列表的左边一半
left_l1 = l1[:middle]
print(left_l1)
return get(left_l1, target_num)
else:
print('找到啦')
get(l1, 234)
如果需要查找的数据在数据集的开头或结尾,那使用二分法反而变得复杂,不如使用for循环来的快
'''面试题,要能手写出来'''
三元表达式
在我们判断条件只需要二选一时,三元表达式更简单
学习三元表达式之前使用版:
username = 'tank'
if username == 'tank':
print('对啦')
else:
print('错啦')
针对if else 分支优化
if usernmae == 'tank': print('对啦')
else:print('错啦')
三元表达式
res = '对啦' if username == 'tank' else '错啦'
print(res)
工作原理:
"""数据值1 if条件 else 数据值2
条件不成立则使用数据值2, 条件成立则使用数据值1"""
需要使用一个变量名来接收结果
各种生成式(也可叫 表达式/推导式)
1.列表生成式
l1 = ['jason', 'tank', 'tony']
new_list = []
使用For循环方法:
for i in l1:
data = f'{i}牛逼'
new_list.append(data)
print(new_list)
列表生成式:
res = [f'{i}牛逼' for i in l1]
print(res) # ['jason牛逼', 'tank牛逼', 'tony牛逼']
复杂情况
res = [f'{i}牛逼' for i in l1 if i == 'tank']
print(res) # ['tank牛逼']
还具备筛选能力
res = ['鸣人' for i in l1 if i != 'jason'] # 此时后面的if时筛选功能
print(res) # ['鸣人', '鸣人']
在加入一个三元表达式
res = ['鸣人' if i == 'jack' else '佐助' for i in l1 if i != 'tank']
print(res) # ['佐助', '佐助']
2.字典生成式
enumerate 当你在循环一个数据集的时候给你产生从0开始的数字,也可以修改起始号码 在后面+ start= 20
变量名接收 = {k:v for循环 k,v in enumerate目标数据集}
l1 = ['jason', 'tank', 'tony']
for i,j in enumerate(l1,): # i 接收序号, j接受数据值
print(i,j)
0 jason
1 tank
2 tony
d1 = {i:j for i, j in enumerate(l1)} # i代表k:j代表v 来处理后面循环获取数据的i j
print(d1)
{0: 'jason', 1: 'tank', 2: 'tony'}
3.元组生成式,集合生成式
元组其实没有生成式 ,产生的结果是生成器
l1 = ['jason', 'tank', 'tony']
res = (i+'sb' for i in l1)
print(res)
# <generator object <genexpr> at 0x0000027BDBEECB30>
用for循环来查看数据:
for k in res:
print(k)
jasonsb
tanksb
tonysb
集合生成式
res = {i for i in 'hello'}
print(res)
匿名函数
没有函数名的函数,需要使用关键字 lambda
lambda 就是用来顶替掉一些简单的函数 , 结合一些常见的内置函数一起用。
语法结构:
lambda 形参:返回值
普通函数方式:
def func(a,b):
return a+b
res = func(2, 3)
print(res) # 5
lambda 方式:
res = lambda x, y: x * y
a = res(2, 3)
print(a) # 6
res = lambda x, y: x * y
print(res(2, 3)) # 6
"""
def func(a, b) 是def的声明部分,return a+b 是实现部分
lambda x,y是声明部分,x * y是实现部分
"""
作业:
附加题
有下列用户数据
user_data = {
'1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
'2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
'3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
}
并有三个函数
def func1():
pass
def func2():
pass
def func3():
pass
要求:调用上述三个函数的时候需要从user_data中校验用户身份是否正确
并获取当前登录用户拥有的可执行函数功能编号即键access对应的功能编号列表
func1是1、func2是2、func3是3
并且一旦用户登录成功之后后续函数的调用不再校验用户身份
请思考如何获取函数功能编号 如何校验用户身份 如何校验权限
ps:装饰器知识 附赠:实现上述主体功能即可 其他扩展优化功能可暂且不写
'''
1.先编写校验用户身份的装饰器
2.然后再考虑如何保存用户登录状态
3.再完善各种需求
'''
user_data = {
'1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
'2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
'3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
}