zoukankan      html  css  js  c++  java
  • 递归、二分法、三元表达式及内置函数和匿名函数

    今天学习的内容有:

    函数递归

    算法中的二分法

    三元表达式

    列表生产式、字典生成式

    匿名函数

    常用的内置函数

    函数递归

    函数的递归:函数在调用阶段直接或者是间接的调用了自身。

    #举个例子
    def func():
        print('from func')
        func()  # 当函数执行到这一步时又一次调用了函数自身
    func()

    上面这个列子实际是一个无限循环的,但是函数不应该无限循环下去,因为每一次调用函数都会产生一个属于它的名称空间,如果无限循环下去,那么就会尝试内存溢出的问题,于是python中有了一个递归层数的限制。

    #我们通过改变上面的程序来查看这个限制是多少:
    def func(n):
          print('from func',n)  # 将n的值打印出来
          func(n+1)  # 每次递归让n加一
    
    func(1)  # 从1开始

    根据测试的结果我们可以得到python强制控制的递归层数大概是997。

    这个递归深度的最大值是可以修改的,要用到一个函数

    import sys
    print(sys,setrecursionlimit(100000))

    递归函数的作用

    函数的递归分为两个阶段:

    1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都应该下降

    直到有一个最终的结束条件。

    2.递推:一次次往回推导的过程

    """举个栗子:你要问a的年龄,a告诉你他比b大2岁,然后你问b,b告诉你他比c大2岁,接着你问c,c告诉你他比d大2岁,最后你问d,d说他18岁。
    理一下这个顺序我们可以得到:
    a=b+2    age(4)=age(3)+2  
    b=c+2    age(3)=age(2)+2
    c=d+2    age(2)=age(1)+2
    d=18     age(1)=18                """
    #然后我们通过函数将这个过程写出来
    def age(n):
        if n ==1:  
              return 18
        else:
              return age(n-1) +2  
    
    print(age(4))     

    这个函数在运行过程中回溯和递推的过程是这样的:

    # 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)
    l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]]
    #根据这个要求我们可以通过for循环来实现,那么使用递归的方法来写一下
    def get_num(l):
        for i in l:  # 从列表里拿出一个元素
            if type(i) is int:  # 判断是否为整型,如果为整型进行下一步,将它打印出来
                print(i)
            else:
                get_num(i)  # 如果不为整型则再次调用函数,就是将列表中的小列表拿出来再循环
    
    get_num(l)

    ps:递归函数不要考虑循环的次数,要把握循环结束的条件。

    算法中的二分法

    #算法能够提高解决问题的效率
    #二分法要求是容器类型中的数字必须有大小顺序
    l=[1,3,5,12,57,89,101,123,146,167,179,189,345]
    target_num = 100
    def get_num(l,target_num):  # 传参,需要传入被索引的列表,和需要索引的值
        if not l:  # 判断要索引的值是否在列表中
            print('不在这里')
            return 
        print(l) 
        middle_index = len(l)//2  # 取列表的长度一半的那个序号,也就是列表的中间值
        if target_num > l[middle_index]:  # 将要缩印的值与列表的中间值进行比较如果大,就取列表的右半部分
            num_right = l[middle_index+1:]  # 切取列表的右半部分
            get_num(num_right,target_num)  # 将列表的右半部分作为参数,调用循环
        elif target_num < l[middle_index]:  # 如果小于中间值就取列表的左半部分
            num_left = l[0:middle_index]  # 切取列表的左半部分  
            get_num(num_left,target_num)  # 将列表的左半部分,调用循环
        else:
            print('bingo',target_num)  # 当被索引的值等于中间值时,输出
    
    get_num(l,target_num)

    三元表达式

    #三元表达式一般用在比如一个条件成立就输出结果1否则就输出结果2这种简单的情况。
    #举个栗子:当我们进行x,y之间的大小判断时会这样写
    def my_max(x,y)
          if x > y:
              return x
          else:
              return y
    #如果用三元表达式来写的话:
    res = x if x > y else y
    print(res)
    
    #意思就是当if成立时返回if前面的值,当if不成立时返回else后面的值。
    三元表达式的固定表达式
            值1 if 条件 else 值2 
                   条件成立 值1
                   条件不成立 值2

    综上可得,三元表达式只推荐在只有两种情况的可能下使用。

    列表生成式

    l = ['tank','nick','oscar','sean']
    l1 = []
    #要求,将列表中的字符串加一个后缀
    #我们可以通过for循环来实现
    for name in l :  # 将名字从列表中循环取出
        l1.append('%s_ad'%name)  # 将名字加上后缀然后添加进新列表
    print(l1)
    
    #用列表生成式来写
    res=['%s_AD'%name for name in l]
    print(res)
    
    #取出某个后缀的元素
    l = ['tank_ad','nick_ad','oscar_ad','sean_ad','jason_ap']
    res = [name for name in l if name.endswith('_ad')]
    #首先,先用for循环依次取出列表中的每一个元素
    #然后使用if进行判断,判断成立之后交给for前面的代码
    #如果当前的元素是条件不能成立则直接舍弃
    #后面不支持再加else的情况了
    print(res)

    字典的生成式

    l1 = ['name','password','hobby']
    l2 = ['jason','123','DBJ','egon']
    #要求,将l1和l2合成一个字典
    d={}
    for i,j in enumerate(l1):
        d[j]=l2[i]
    print(d)
    
    #用字典生成式快速生成一个字典,并用012作为key值
    l1 = ['jason','123','read']
    d = {i:j for i,j in enumerate(l1)}
    print(d)

    ps:把列表解析的[]换成()得到的就是生成器表达式

    匿名函数

    匿名函数就是没有名字的函数,它的特点是临时存在,用完之后就没了。

    def my_sum(x,y):
        return x + y
    print(my_sum(1,2))
    
    #匿名函数
    res = (lambda x,y:x+y)(1,2)  
    print(res)
    # :的左边相当于函数的形参
    # :的右边相当于函数的返回值

    匿名函数一般情况下都不会单独使用,都是配合内置函数一起使用的。

    常用的内置函数

    #比较工资
    d = {
        'egon':30000,
        'jason':88888888888,
        'nick':3000,
        'tank':1000
    }
    print(max(d,key=lambda name:d[name]))  # 输出工资最高的
    
    print(min(d,key=lambda name:d[name]))  # 输出工资最低的
    
    """
    lambda name:d[name]实际等于下面这个函数
    def index(name):
        return d[name]
    """
    #zip 拉链  # 基于for循环
    l1 = [1,2,]
    l2 = ['jason','egon','tank']
    l3 = ['a','b','c']
    print(list(zip(l1,l2,l3)))
    #将列表中对应位置的元素打包成一个个元组,然后返回一个由这些元组组成的列表。
    #map 映射
    l = [1,2,3,4,5,6]
    print(list(map(lambda x:x+1,l)))
    >>>:[2,3,4,5,6,7]
    from functools import reduce
    l = [1,2,3,4,5,6]
    print(reduce(lambda x,y:x+y,l))  # 19初始值  第一个参数
    # 当初始值不存在的情况下 按照下面的规律
    # 第一次先获取两个元素 相加
    # 之后每次获取一个与上一次相加的结果再相加
    #filter 过滤
    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)) >>>:['egon', 'jason', 'nick', 'tank'] l = ['jason','egon','nick','tank'] print(sorted(l,reverse=True)) >>>:['tank', 'nick', 'jason', 'egon']
  • 相关阅读:
    第3章 管道符、重定向与环境变量
    基于Linux命令行KVM虚拟机的安装配置与基本使用
    Linux系统真正的优势以及学习方法
    一款在线编写接口文档的工具
    springboot前端传参date类型后台处理方式
    软件工程专业需要知道的缩写和专业名词
    七牛云图床及MPIC工具使用
    阿里云ECS云服务器CentOS部署个人网站
    【字】biang
    【车】打开车窗技巧
  • 原文地址:https://www.cnblogs.com/wangnanfei/p/11178162.html
Copyright © 2011-2022 走看看