• 函数(四)


    1.函数递归

    什么是函数递归

      函数递归是函数嵌套的一种,是在函数调用阶段,直接或者间接的又调用自身

    函数递归的演示

    直接调用自身

    def func(n):
        print('递归函数的演示%s'%n)
        print(n)
        func(n+1)  # 又调用了本身
    func(1)

    间接调用自身

    # index()函数内部调用了func()函数
    def index(n):
        print(n)
        func(n+1)
        print(n)
    # func()函数内部又调用了index()函数,导致了递归出现了死循环
    def func(n):
        print(n)
        index(n+1)
    
    index(1)

    在函数内部又调用了自身,导致了重复调用,类似死循环,但是为了防止内存的溢出,python解释器对函数的递归做了限制,大概只能递归998次左右

    我们可以通过添加sys模块人为的更改递归的限制此时

    # sys模块
    import sys
    print(sys.getrecursionlimit())  # 输出递归限制
    sys.setrecursionlimit(2000) # 可以更改递归限制

     

    函数递归的运用

    递归可以在函数内帮我们完成类似循环的操作,但是我们不可能让一个函数无限制的递归下去,这时候我们需要给递归限制一个条件

    递归分为两个阶段

      回溯:函数递归时必须有一个明确的结束条件,并且每次递归的问题复杂程度慢慢下降,这样才能解决问题,否则便是毫无意义的死循环

      递推:到达结束条件之后,一步步的往回推,获取最终结果

    问题1:第一个人是20岁,他比第二个人小2岁,以此类推第10个人是多少岁

    '''
    age1 = 20
    age2 = age1 + 2
    age3 = age2 + 2
    age4 = age3 + 2
    ...
    age(n) = age(n-1) + 2
    '''
    def index(n):
        if n == 1:  # 结束条件
            return 20
        return index(n-1)+2
    
    res = index(10)

    问题2:循环输出l = [1,[2,[3,[4,]]]]

    l = [1,[2,[3,[4,]]]]
    for i in l:
        if type(i) is int:
            print(i)
        else:
            for i1 in i:
                if type(i1) is int:
                    print(i1)
                else:
                    for i2 in i1:
                        if type(i2) is int:
                            print(i2)
                        else:
                            for i3 in i2:
                                if type(i3) is int:
                                    print(i3)

    可以使用for循环来输出,但是这样做很繁琐,一旦数字过大,便很难输出结果

    利用递归解决

    def index(l):
        for i in l:
            if type(i) is int:
                print(i)
            else:
                index(i)
    index(l)

    注意:

      使用递归函数不要考虑循环的次数 只需要把握结束的条件即可

    2.算法之二分法

    什么是算法

      算法是解决问题高效的方法

    问题:求一个数是否在一个列表中

    l = [1,2,3,4,5,6,7,8,9]
    x = 9
    print(x in l)  # 第一种
    for i in l:  # 第二种
        if x == i:
            print('%s在列表中'%x)
        else:
            pass

    这两种方法都是基于for循环,即把每个数字都取出来一个个的进行对比,如果要求的是最后一个数字,则需要比较9次,这样的效率比较低

     

    二分法查找:在有序列表中,先求出列表中间那个数,与被比较数比较,如果大于被比较数,则把小于中间数的数字作为列表,再求这个列表的中间数,再进行比较,直至找到这个数,这样的方法查找次数减少,查找效率提高

    用二分查找法查找一个数

    l = [1,2,3,4,5,6,7,8,80,100]
    def index(x,l):
        if not l:
            print('%s这个数不在列表中'%x)
            return
        key = len(l)//2  # 求列表中间的索引
        if x > l[key]:  # 与列表中间索引对应的值进行比较
            l_right = l[key + 1:]  # 比中间的值大就取右半区
            index(x,l_right)
        elif x < l[key]:
            l_left = l[0:key]  # 比中间的值小就取左半区
            index(x,l_left)
        else:
            print('%s在列表中'%x)  # 相等就打印
    index(80,l)

    注意:用二分法查找的列表一定是有大小顺序的

    3.三元表达式

    函数求数字大小

    def my_max(x,y):
        if x > y:
            return x
        else:
            return y
    
    res = my_max(5,9)
    print(res)

    三元表达式求数字大小

    x = 4
    y = 3
    res1 = x if x > y else y  # 三元表达式表示的是如果条件成立就返回x,条件不成立就返回y
    print(res1)

    三元表达式的固定格式

    # 三元表达式的格式:
        值/代码1 if 布尔值判断 else 值/代码2 
            如果条件成立布尔值为True 则 输出值/代码块1
            如果条件不成立布尔值为False 则 输出值/代码块2

    注意:三元表达式只推荐在只有两个情况的条件下使用,一旦超过两个情况,代码块会变得复杂,不适合使用

    4.列表生成式

    输出一个新列表,并且在每个元素后面添加123

    l = ['sss','xxx','ccc','111']
    # 普通的方法
    l1 = []
    for name in l:
        l1.append('%s123'%name)  # 循环输出每个元素,并在每个字符串后面添加123,再添加入新列表
    print(l1)

     用列表生成式,在每个元素后面添加1234

    # 列表生成式的方法
    l1 = ['%s1234' %name for name in l]  # 直接用列表生成式生成新列表
    print(l1)

    列表生成式后也可以跟if判断式

    l2 = ['%s' %name for name in l1 if name.isdigit() == False]  # 把不是纯数字的元素添加到新列表中
    print(l2)

    先for循环输出列表中的每个元素
    交由if判断,条件成立的元素放入新列表
    条件不成立的元素直接舍弃

    注意:if后面不能再跟else,因为for后面也有else的说法,这样程序不能判断是for的else还是if的else

    5.字典生成式和集合生成式

    传统方法把两个列表一一对应生成一个字典

    # 字典集合生成式
    l1 = ['name','pwd','age']
    l2 = ['sxc','123','18','123']
    d = {}
    for i,j in enumerate(l1):  # 枚举,i相当于列表的索引,j是列表的元素
        print(i,j)
        d[j] = l2[i]
    print(d)

    字典生成式

    d1 = {i:j for i,j in enumerate(l1,1)}  # 字典生成式生成列表
    print(d1)
    d2 = {i:j for i,j in enumerate(l2,1) if i != 2}  # 加if判断条件的表达式,把i==2的情况去掉,后面也不能跟else
    print(d2)

    注意:和列表生成式类似,字典生成式后也可以跟if判断条件,也不能再跟else

    集合生成式

    s1 = {i for i in range(10)}  # 集合生成式
    print(s1)
    s2 = {i for i in range(10) if i != 5}  # 集合生成式加if判断条件,后面也不能跟else
    print(s2)

    注意:和列表生成式类似,集合生成式后也可以跟if判断条件,也不能再跟else

    生成式表达式:没有元组生成式,只有生成式表达式(相当于一个老母猪)

    t1 = (i for i in range(10) if i != 6)  # 这样写不是元组生成式,而是生成器表达式,相当于老母猪
    print(t1)
    for i in t1:
        print(i)

    6.匿名函数

    匿名函数不再使用def的标准定义一个函数,而是使用lambda来创建匿名函数,匿名函数顾名思义是没有函数名的函数

    匿名函数有自己的名称空间,并且只能访问自己参数列表的名称,不能访问其他或者全局名称空间的名称

    匿名函数lambda只是一个表达式,函数体比def简单的多,并且他只能封装有限的逻辑表达式

    匿名函数的特点:临时存在,用完就没了

    求两个数的和

    def sum(x,y):
        return x + y
    res = sum(1,2)
    print(res)

    匿名函数求和

    res1 = (lambda x,y:x+y)(3,4)  # 匿名函数的第一种写法
    print(res1)
    res3 = lambda  x,y:x+y  # 匿名函数的第二种写法
    print(res3)  # 这是函数对应的地址空间
    print(res3(5,6))

    匿名函数的语法:(匿名函数lambda 匿名函数对应的形参  :   匿名函数对应的返回值)(匿名函数的实参)

    匿名函数通常不会单独使用,是配合内置函数一起使用的

    7.常用的内置函数

    Python内置函数有很多

    常用的一共约有69个内置函数

    max()函数

      max(x,y,z...) 方法返回给定参数的最大值,参数可以为序列,内部是基于for循环的

    l = [1,2,3,4,5]
    print(max(l))  # 求最大值,内部是基于for循环的

    max()+内置函数lambda的运用

    d = {
        'sxc':30000,
        'zzj':88888888888,
        'zzp':3000,
        'lzx':1000
    }
    # 求value的最大值,返回对应key的值
    print(max(d,key = lambda name :d[name]))
    # 求value的最小值,返回对应key的值
    print(min(d,key = lambda name :d[name]))

    map(函数,一个或多个序列)映射

      按照序列的索引执行前面的函数

    l1 = [1,2,3,4,5]
    l2 = [5,4,3,2,1]
    res = map(lambda x,y:x+y,l1,l2)  # 定义一个匿名函数,输入两个列表按照索引执行函数
    print(list(res))

    zip(可迭代的对象)拉链

      把多个迭代器内的内容按照索引分别组合成一个个元组,也是基于for循环的

    l1 = ['姓名:sxc','姓名:zzj','姓名:zzp']
    l2 = ['年龄:18','年龄:19','年龄:20']
    l3 = ['密码:123','密码:234','密码:345']
    res = zip(l1,l2,l3)
    print(res)  # 老母猪
    print(list(res))  # 可以用list来转换输出列表

    filter(判断布尔值的函数,可迭代的对象)

      用函数判断可迭代的对象的True和False,True的输出,False的丢弃

    l = [9,7,5,3,1]
    res = filter(lambda x:x > 4,l)  # 输出布尔值为True的l中的元素
    print(res)
    print(list(res))

    sorted(可迭代对象,key,reverse)升序,降序

      对可迭代对象的升序降序,reverse = True降序,reverse = False升序

      sorted与list.sort的不同是前者重新创建了一个列表,后者把原列表重新声明了,相当于修改了原列表

    l = [1,2,3,4,5,6]
    res = sorted(l,reverse=True)  # 降序
    print(res)

    reduce(函数,可迭代对象,初始值) 函数会对参数序列中元素进行累积

      两个及以上的可迭代对象的数据按照函数累积,可以指定初始值

    from functools import reduce
    l = [1,2,3,4,5,6]
    res = reduce(lambda x,y:x+y,l)  # 不指定初始值1+2+3+4+5+6
    print(res)
    res1 = reduce(lambda x,y:x+y,l,100)  # 初始值指定为100,100+1+2+3+4+5+6
    print(res1)

     12

  • 相关阅读:
    在ts+vue中实现前端批量下载打包二维码
    常用到的MD5加密
    Permission denied Command PhaseScriptExecution failed with a nonzero exit code
    iOS App 内购 Demo
    App 上架遇到的坑
    基于StreamingKit的音频播放器
    iOS 添加多图片加签名
    xcode10 自定义代码块
    xcode10 之后代码不联想
    Mac 开发PHP 使用ThinkPHP
  • 原文地址:https://www.cnblogs.com/sxchen/p/11177295.html
Copyright © 2020-2023  润新知