内容回顾
- 算法之二分法
- 三元表达式
- 各种生成式
- 匿名函数
- 内置函数
算法之二分法
1.什么是算法
解决问题的高效办法
2.算法的应用场景
推荐算法(抖音视频推送 淘宝商品推送)
成像算法(AI相关)...
几乎涵盖了我们日常生活中的方方面面
3.二分法
是算法中最简单的算法 甚至都称不上算法
'''
二分法使用要求:
待查找的数据集必须有序
二分法的缺陷:
针对开头结尾的数据查找效率很低
常见算法的原理以及伪代码:
二分法、冒泡、快拍、堆排、桶排、数据结构(链表 约瑟夫问题 如何链表是否成环)
'''
l1 = [11, 33, 34, 54, 56, 78, 93, 134, 678, 875, 945, 2013, 3903, 4909, 5001]
# 查找列表中某个数据值
# 方式一:for循环 次数较多
# 方式二:二分法 不断地对数据集做二分切割
# 定义一个要找的数据值 target_num = 875
def get_num(l1, target_num):
5.添加一个结束条件
if len(l1) == 0:
print('很抱歉 没找到')
return
1.获取列表中间索引值
middle = len(l1) // 2
2.比较目标数据值与中间索引值的大小
if target_num > l1[middle]:
3.比较切片出来的是右边一半
regiht_l1 = l1[middle+1:]
4.把右边一半的列表继续做二分法判断 >>> 又要调用函数想到递归函数
return get_num(regiht_l1, targer_num)
2.1比较目标数据值与中间索引值的大小
elif target < l1[middle]:
3.1比较切片出来的是左边一半
left_l1 = l1[:middle]
4.1把左边一半的列表继续做二分法判断 >>> 又要调用函数想到递归函数
return get_num(left_l1, target_num)
else:
print('找到了')
get_middle(l1, 875) # 找到了
get_middle(l1, 2000) # 很抱歉 没找到
三元表达式
# 当需求仅仅是二选一的情况下 那么推荐使用三元表达式
def num_max(a, b):
if a > b:
return a
else:
return b
# 三元表达式
def num_max(a, b):
return a if a > b else b
name = 'jason'
if name == 'jason':print('老师') # 简化步骤:简单代码只有一行 那么可以直接在冒号后面编写
else:print('老师')
# 三元表达式
res = '老师' if name == 'jason' else '学生'
print(res)
'''
数据值1 if 条件 else 数据值2
条件成立则使用数据值1 条件不成立则使用数据值2
不推荐多个三元表达式嵌套
'''
各种生成式/表达式/推导式
name_list = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
# 给列表中所有人名的后面加上_NB的后缀
'''传统做法'''
new_list = []
for name in name_list:
new_name = f'{name}_NB'
new_list.append(new_name)
print(new_list)
'''列表生成式'''
res = [name + '_NB' for name in name_list]
# res = ['%s_NB' % name for name in name_list]
# res = [f'{name}_NB'for name in name_list]
print(res) # ['jason_NB', 'kevin_NB', 'oscar_NB', 'tony_NB', 'jerry_NB']
'''复杂情况'''
new_list = [name + '_NB' for name in name_list if name == 'jason']
print(new_list) # ['jason_NB']
new_name = ['大赤佬' if name == 'jason' else '大赤佬' for name in name_list if name != 'jason']
print(new_name) # ['小赤佬', '小赤佬', '小赤佬', '小赤佬']
'''字典生成式'''
# 枚举
'''
enumerate() 针对该方法使用的for循环取值
每次会产生两个结果
第一个是从0开始的数字
第二个是被循环的对象里面的元素
'''
s1 = 'hello wrold'
for j, i in enumerate(s1):
print(j, i) # 打印出来的结果一个是j从0开始的数字 一个是i被循环对象中的元素
for i, j in enumerate(s1, start=100):
print(i,j) # 打印出来的结果是从一个100开始的数字 一个是被循环对象中的元素
d1 = {i:j for i, j in enumerate(s1)} # i是从0开始的数字 j是被循环对象中的元素
print(d1) # {0: 'h', 1: 'e', 2: 'l', 3: 'l', 4: 'o', 5: ' ', 6: 'w', 7: 'o', 8: 'r', 9: 'l', 10: 'd'}
'''集合生成式'''
res = {i for i in 'hello'}
print(res) # 无序去重{'h', 'l', 'o', 'e'}
'''元组生成式''' 没有元组生成式 下列的结果是生成器
匿名函数
# 匿名函数:没有名字的函数 需要使用关键字lambda
'''
语法格式
lambda 形参:返回值
'''
print(lambda x: x**2) # <function <lambda> at 0x000001F0817D60D0>
def index():
pass
print(index) # <function index at 0x000001F0817D60D0>
res = lambda x: x ** 2
print(res(2)) # 4
使用场景
lambda a, b: a+b
匿名函数一般不单独使用 需要配合其他函数一起使用
常见内置函数
1.map() 映射
l1 = [1, 2, 3, 4, 5, 6]
# 给列表中的每一个元素加1
def func(a):
return a + 1
res = map(func, l1) # 循环获取l1列表中每一个元素并传递给func函数再保存返回值
print(res) # <map object at 0x000002598FB4B470>
print(list(res)) # [2, 3, 4, 5, 6, 7]
ret = map(lambda s: s+1, l1) # 循环获取l1列表每一给元素并传递给匿名函数保存返回值
print(list(ret)) # [2, 3, 4, 5, 6, 7]
2.max() \ min()
l1 = [22, 33, 44, 55]
res = max(l1)
print(res) # 55
ret = min(l1)
print(ret) # 22
d = {
'jason':3000,
'Bevin':1000000,
'Ascar':10000000000,
'aerry':88888
}
# 取出数字最大的人
错误用法 print(max(d)) # jason
'''
A-Z: 65-90
a-z: 97-122
'''
def func(k):
return d[k]
print(max(d, key=func)) # Ascar
print(max(d, key=lambda k: d.get(k))) # Ascar
3.reduce 传多个值 返回一个值
# reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
l1 = [22, 33, 22, 44, 77, 55, 88, 99, 33]
res = reduce(lambda a, b: a + b, l1) # a:22 b:33得到55则 a:55 b:22得到77则 a:77 b:44....
print(res) # 473
rel = reduce(lambda a, b: a * b, l1)
print(rel) # 855652058110080
ret = reduce(lambda a, b: a + b, l1, 100) 还可以添加值 # a:100 b:22得到122则 a:122 b:33得到155则a:155 b:22
print(ret) # 573
练习
有下列用户数据
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:装饰器知识 附赠:实现上述主体功能即可 其他扩展优化功能可暂且不写
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']}
}
tag_dict = {"user": None, "index": None}
def login():
user = input('请登入您的账号>>>:').strip()
password = input('请输入你的密码>>>:').strip()
return user, password
def login_auth(mode):
def outer(func):
def inner(*args, **kwargs):
if tag_dict['user'] == None:
user, password = login()
for data in user_data:
if user_data[data].get('name') == user and user_data[data].get('pwd'):
print('登入成功')
tag_dict['user'] = user
tag_dict['index'] = mode
if mode in user_data[data].get('access'):
res = func(*args, **kwargs)
return res
else:
print('对不起你没有权限!')
return
else:
print('用户名或密码错误')
return
else:
tag_dict['index'] = mode
for i in user_data:
if user_data[i]['name'] == tag_dict['user']:
if tag_dict['index'] in user_data[i]['access']:
res = func(*args, **kwargs)
return res
else:
print('对不起你没有权限')
return inner
return outer
@login_auth('1')
def func1():
print('执行功能项1')
@login_auth('2')
def func2():
print('执行功能项2')
@login_auth('3')
def func3():
print('执行功能项3')
dic = {
'1': func1,
'2': func2,
'3': func3,
}
while True:
print('''
1.功能项1
2.功能项2
3.功能项3
''')
choice = input('请选择您的功能项>>>:').strip()
if choice in dic:
res = dic.get(choice)()
else:
print('暂无该功能项')