第十章:算法、表达式与其它函数类型

递归函数

官网提供的最大递归深度为1000,python解释器添加的安全措施,我们在测试的时候可能会出现 996 997 998

递归函数的特点:

  1. 直接或者间接调用自己

  2. 每次调用都必须比上一次简单 并且需要有一个明确的结束条件

    递推:一层层往下
    回溯:基于明确的结果一层层往上

def get_age(n):
    if n == 1:
        return 18
    return get_age(n-1) + 2
res = get_age(5)
print(res)

超过最大递归限制的报错
只要写递归函数,必须要有结束条件。

返回值

  1. 不要只看到return就认为已经返回了。要看返回操作是在递归到第几层的时候发生的,然后返回给了谁
  2. 如果不是返回给最外层函数,调用者就接收不到
  3. 需要再分析,看如何把结果返回回来

算法

什么是算法

算法就是解决问题的有效方法,但不是所有的算法都很高效,也有不合格的算法。

算法应用场景有:
推荐算法(抖音视频推送 淘宝商品推送)
成像算法(AI相关)......
几乎涵盖了我们日常生活中的方方面面

我们现在学习的算法都是过去时的
了解基础的算法,才能创造出更好的算法
 不是所有的事情都能套用现成的方法解决的
 有些时候会用到学过的算法知识来解决新的问题

二分法

​ 是算法中最简单的算法,甚至都称不上是算法

二分法使用要求
    待查找的数据集必须有序
二分法的缺陷
    针对开头结尾的数据 查找效率很低
常见算法的原理以及伪代码
    二分法、冒泡、快拍、插入、堆排、桶排、数据结构(链表 约瑟夫问题 如何链表是否成环)

例子:

l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
# 查找列表中某个数据值
# 方式1:for循环  次数较多
# 方式2:二分法 不断的对数据集做二分切割
'''代码实现二分法'''
# 定义我们想要查找的数据值
# target_num = 987
lit = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
target_num = 987
find_num = 0

def dichotomy(lits, target_num = 987):
    global find_num
    index_moddle = len(lits) // 2
    find_num += 1
    if len(lit) == 0:
        print('未找到该值')
        return -99999
    if lits[index_moddle] > target_num:
        new_lit = lits[:index_moddle]
        return dichotomy(new_lit, target_num)
    elif lits[index_moddle] < target_num:
        new_lit = lits[index_moddle + 1:]
        return dichotomy(new_lit, target_num)
    elif lits[index_moddle] == target_num:
        print('找到了,查找次数为:{}'.format(find_num))
        return find_num


ret = dichotomy(lit, target_num)
print('ret', ret)

三元表达式

代码简单并且只有一行,那么可以直接在冒号后面编写
当结果是二选一的情况下使用三元表达式较为简便,并且不推荐多个三元表达式嵌套

伪代码格式:Ture if 条件 else False
描述:条件成立则返回 Ture 条件不成立则返回 False
falg = 0
val = -99999 if falg == 0 or falg == Nono else falg

列表表达式

列表:list

name_list = ['600600', '600000', '600001', '600002', '600003']
# 给列表中所有人名的后面加上前缀:SH
# 列表生成式
SH_lit = ['SH' + i for i in name_list]
print(SH_lit)   # ['SH600600', 'SH600000', 'SH600001', 'SH600002', 'SH600003']
# 复杂情况:存在判断条件
name_list = ['600600', '600000', '600001', '000001', '000002']
# if
new_list = ['SZ' + name for name in name_list if name[0] in ['0', '2', '3', '4', '8']]
print(new_list) # ['SZ000001', 'SZ000002']
# if ... else ...
new_list = ['SZ' + name if name[0] in ['0', '2', '3', '4', '8'] else 'SH' + name for name in name_list ]
print(new_list) # ['SH600600', 'SH600000', 'SH600001', 'SZ000001', 'SZ000002']

字段:dict

name_lit = ['ysg|123', 'hw|12345', ]
d1 = {i.split('|')[0]:i.split('|')[1] for i in name_lit}
print(d1)   # {'ysg': '123', 'hw': '12345'}

集合:set

res = {i for i in 'hello'}
print(res)  # {'o', 'l', 'e', 'h'}

匿名函数

没有名字的函数 需要使用关键字:lambda
语法结构
	lambda 形参:返回值
使用场景
	lambda a,b:a+b
匿名函数一般不单独使用 需要配合其他函数一起用
# 使用 reduce() 和 lambda 函数计算乘积
# reduce 函数接受两个参数:一个函数和一个序列。
# 第一个参数: 使用 lambda 函数定义了一个简单的乘法操作 x * y,其中 x 和 y 是列表中的元素。
# 第二个参数: numbers 列表。
# reduce 会从 numbers 列表中的前两个元素开始,计算它们的乘积,然后用这个乘积与下一个元素继续计算,直到遍历完整个列表。

from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
 
print(product)  # 输出:120

作业

1.附加题
  有下列用户数据
    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']}
}

解答

user_data = {
        '1': {'name': 'ysg', 'pwd': '123', 'access': ['1', '2', '3']},
        '2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
        '3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
    }


is_start = False
user_acc = None
is_login = {
    'login_status': False,  # 记录用户是否登录
    'user_access': None  # 记录登录用户的权限
}

def login_out(num):
    def outer(func):
        def inner(*args, **kwargs):
            if is_login['login_status']:
                if num in is_login['user_access']:
                    ret = func()
                    return ret
                else:
                    print('权限不存在')
            else:
                input_num = input('请输入编号>>>').strip()
                if input_num in user_data and is_login['user_access']:
                    if num in is_login['user_access']:
                        ret = func()
                        return ret
                    else:
                        print('编号不存在')

                user = input('请输入用户名>>>').strip()
                pwad = input('请输入密码>>>').strip()
                if user == user_data[num]['name'] and pwad == user_data[num]['pwd']:
                    ret = func()
                    is_login['login_status'] = True
                    is_login['user_access'] = user_data[num]['access']
                    print('登录成功')
                    return ret
        return inner
    return outer


@login_out('1')
def func1():
    print('函数 func1')

@login_out('2')
def func2():
    print('函数 func2')

@login_out('3')
def func3():
    print('函数func3')


func1()
func2()
func3()
posted @ 2022-10-17 07:52  亦双弓  阅读(197)  评论(0)    收藏  举报