• Python之函数的递归、匿名函数、内置函数


    一、函数的递归

    '''
    1 什么是函数递归
        函数递归调用(是一种特殊的嵌套调用):在调用一个函数的过程中,又直接或间接地调用了该函数本身
    
        递归必须要有两个明确的阶段:
            递推:一层一层递归调用下去,强调每进入下一层递归问题的规模都必须有所减少
            回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推(明确的结束条件即递归出口)
                开始一层一层回溯
    
        递归的精髓在于通过不断地重复逼近一个最终的结果
         递归(Recursion),在数学与计算科学中,是指在函数定义中使用函数自身的方法
    2、为什么要用函数递归
    
    
    3、如何用
    '''
    
    
    
    # 递归的优缺点:
    # 优点:
    # 递归是代码看起来更加整洁、优雅
    # 可以用递归将复杂任务分解成简单的子问题
    # 使用递归比使用一些嵌套迭代更容易
    #
    # 缺点:
    # 递归的逻辑很难调试、跟进
    # 递归调用的代价高昂(效率低),因为占用了大量的内存和时间
    
    # import sys
    # print(sys.getrecursionlimit())                #可以限制递归的次数,防止无限递归,过多的占用内存
    # # sys.setrecursionlimit(3000)                 #可以设置递归的次数
    # def foo(n):
    #     print('from foo',n)
    #     foo(n+1)                                 #直接有调用了函数自己本身
    # foo(0)
    
    
    # 递归间接的调用它本身
    # def bar():
    #     print('from bar')
    #     foo()
    #
    # def foo():
    #     print('from foo')
    #     bar()
    # foo()
    
    
    # 递归的应用:
    # 知道第一个人的年龄,计算第五个人的年龄
    # age(5) = age(4) + 2                 #递归一层一层的进行下去,递归的问题规模都在减少
    # age(4) = age(3) + 2
    # age(3) = age(2) + 2
    # age(2) = age(1) + 2
    # age(1) = 26                        #递归必须要有一个明确的结束条件
    
    # age(n) = age(n-1) + 2 #n > 1
    # age(1) = 26           #n = 1
    
    # def age(n):
    #     if n == 1:
    #         return 26                 #递归有一个明确的结束条件
    #     return age(n-1) + 2           #一层一层的递推下去,问题的规模不断的缩小
    #
    # print(age(5))
    
    
    # 取出嵌套列表中的每一个元素
    # 递归的循环:
    # l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
    # def tell(l):
    #     for item in l:
    #         if type(item) is list:
    #             #继续进入下一层递归
    #             tell(item)
    #         else:
    #             print(item)
    # tell(l)
    
    
    
    # 有一个从小到大排列的整型数字列表
    # nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]
    # # 10 in nums
    # for item in nums:
    #     if item == 10:                  #使用for循环要将其中的每一个循环一遍可能才能找到我们想要找的值
    #         print('find it')
    #         break
    # else:
    #     print('not exists')
    
    
    
    
    # 二分法:
    #使用二分法可以快速找到我们要找的值
    # nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]
    # def search(search_num,nums):                #传入要查找的数字,和要比较的原列表
    #     print(nums)
    #     if len(nums) == 0:                     #经过二分法后得到的列表,列表长度为0,说明进行最后一个二分法也没有匹配成功,说明要查找的数字不在列表中
    #         print('not exists')
    #         return                            #直接结束函数的运行
    #     mid_index=len(nums) // 2              #拿到列表的长度进行二分法取整      5----比较----[1,2,3,4,5,6]------第一次索引3-----切片[4:]----->[5,6]
    #     if search_num > nums[mid_index]:      #拿要查询的数字与二分法得到的索引对应列表中的值进行比较大小,
    #         # in the right
    #         nums=nums[mid_index+1:]          #此时筛选掉列表中一半的值,使用切片拿到筛选到的结果
    #         search(search_num,nums)          #使用递归的方法,传入要查询的值,和新得到的列表,进一步进行判断
    #     elif search_num < nums[mid_index]:   #查询的数小于二分法中得到的中间值,则使用切片拿到左半边的列表的所有值
    #         # in the left
    #         nums=nums[:mid_index]
    #         search(search_num,nums)         #重复递归,直到切出我们要查询的值
    #     else:
    #         print('find it')                #要查询的值既不大于也不小于二分法得到得值,切分的结果也不为空列表,说明要查询的数字肯定在列表中,即找到要查询的值
    # search(31,nums)
    
    
    # nums=[i for i in range(101)]
    # # print(nums)
    # def tell(search_num,nums):
    #     if len(nums)==0:
    #         print('要查找的数字不在列表中')
    #         return
    #     mid_index=len(nums)//2
    #     if search_num>nums[mid_index]:
    #         nums=nums[mid_index+1:]
    #         tell(search_num,nums)
    #     elif search_num<nums[mid_index]:
    #         nums=nums[:mid_index]
    #         tell(search_num,nums)
    #     else:
    #         print('find it')
    # tell(35,nums)

    二、匿名函数

    # 有名函数:基于函数名重复使用
    # def func():
    #     print('from func')
    #
    # func()               #有名函数可以被重复的调用
    # func()
    # func()
    
    
    # 匿名函数:没有绑定名字的下场是用一次就回收了
    # def func(x,y): #func=函数的内存地址
    #     return x + y
    # print((lambda x,y:x+y))          #<function <lambda> at 0x0000015F53212BF8>对应一个函数的内存地址,所以加括号就可以调用
    # res=(lambda x,y:x+y)(1,2)      #冒号左边是参数,右边是匿名函数的返回值
    # print(res)                     #返回值为:3
    
    # f=lambda x,y:x+y                 #匿名函数又赋值给了一个变量,通常匿名函数都是结合其他内置函数使用的,且只使用一次
    # print(f)
    # print(f(1,2))
    
    # 匿名函数与下面的内置函数结合的应用
    #max min map filter sorted
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    
    # max的工作原理
    #1 首先将可迭代对象变成迭代器对象
    #2 res=next(可迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据
    def func(k):
        return salaries[k]                  #比较的依据即执行函数体代码,拿到的返回值
    print(max(salaries,key=func)) #next(iter_s),max取出来的值永远不会变,key改变比较依据,最终拿到的还是max进行next的结果
    #可以将上式转换成匿名函数的形式,即max结合匿名函数的应用
    # 'egon', v1=func('egon')
    # 'alex', v2=func('alex')
    # 'wupeiqi', v3=func('wupeiqi')
    # 'yuanhao', v4=func('yuanhao')
    
    
    # max+lambda 的应用
    # min+lambda 的应用
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    print(max(salaries,key=lambda k:salaries[k])) #next(iter_s)max内有两个参数,左变是要比较的迭代的对象,右边是key=一个函数
    print(min(salaries,key=lambda k:salaries[k])) #next(iter_s)
    
    
    # l=[10,1,3,-9,22]
    # l1=sorted(l,reverse=False)    #sorted默认是按照从左到右,从小到大的顺序进行排列的,reverse默认为Flase
    # print(l1)
    
    # l2=sorted(l,reverse=True)      #reverse=True时,排列顺序则变为从大到小的顺序进行排列
    # print(l2)
    
    # sorted+lambda应用
    # 将字典中所有人名按照薪资,从大到小的顺序进行排列
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    #排列对象可迭代对象,比较方式:通过value进行比较,排列顺序:按照从大到小的顺序
    print(sorted(salaries,key=lambda k:salaries[k],reverse=True))
    
    
    names=['张明言','刘华强','苍井空','alex']
    # map的工作原理
    #1 首先将可迭代对象变成迭代器对象
    #2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一
    
    # map+lambda 的应用
    aaa=map(lambda x:x+"_SB",names)    #map跟两个参数,左边是一个函数,右边是一个可迭代对象,
    print(aaa)                         #<map object at 0x000001FDB7D39A90>是一个迭代器,使用list就可以迭代取出其中的值
    print(list(aaa))                   #['张明言_SB', '刘华强_SB', '苍井空_SB', 'alex_SB']
    
    print([name+"_SB" for name in names])        #['张明言_SB', '刘华强_SB', '苍井空_SB', 'alex_SB']------列表生成式的应用
    
    # filter的工作原理
    #1 首先将可迭代对象变成迭代器对象
    #2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下res
    names=['alexSB','egon','wxxSB','OLDBOYSB']
    # print([name for name in names if name.endswith('SB')])
    
    # filter+lambda 的应用
    aaa=filter(lambda x:x.endswith('SB'),names)    #filter左边跟一个函数,右边跟一个可迭代对象
    print(aaa)                                     #<filter object at 0x00000157DB717A20>---filter产生的也是一个迭代器,通过list也可以迭代取出其中的值
    print(list(aaa))                               #['alexSB', 'wxxSB', 'OLDBOYSB']

    三、内置函数

    # 掌握
    # res='你好'.encode('utf-8')    #encode编码成bytes格式
    # print(res)                    #b'xe4xbdxa0xe5xa5xbd'
    #
    # res=bytes('你好',encoding='utf-8')
    # print(res)                    #b'xe4xbdxa0xe5xa5xbd'
    
    # 参考ASCII表将数字转成对应的字符
    # print(chr(65))
    # print(chr(90))
    # 参考ASCII表将字符转成对应的数字
    # print(ord('A'))
    #
    
    #3是11//3取整,2是11%3取余
    # print(divmod(11,3))             #(3, 2)---可以用再页面的显示页数,如淘宝购物页面信息,有1001条信息,一页最多显示100条,则此时需要11页才能将所有的信息显示完
    
    
    # l=['a','b','c']
    # for item in enumerate(l):       #enumerate经for循环,取出可迭代对象的索引与其对应的值
    #     print(item)
    
    # l='[1,2,3]'
    # l1=eval(l)                      #eval将字符串中的列表取出来,从而可以对其进行取值
    # print(l1,type(l1))
    # print(l1[0])
    
    # eval的应用---------------------可以将字符串转换为列表、字典、元组
    s1="['egon',18,'male']"
    s2="{'name':'egon','age':18,'sex':'male'}"
    s3="('egon',18,'male')"
    print(eval(s1))
    print(eval(s2))
    print(eval(s3))
    print(type(eval(s1)))
    print(type(eval(s2)))
    print(type(eval(s3)))
    # with open('a.txt',encoding='utf-8') as f:
    #     data=f.read()
    #     print(data,type(data))
    #     dic=eval(data)                 #将从文件中取出的字符串中的表达式,通过eval转换成字典
    #     print(dic['sex'])
    
    # print(pow(3,2,2)) # (3 ** 2) % 2   #1--------pow中三个参数,即3的2次方除2取余
    
    # print(round(3.3))                  #round四舍五入
    
    # print(sum(range(101)))             #求和------1到100的和
    
    
    # module=input('请输入你要导入的模块名>>: ').strip() #module='asdfsadf'
    # m=__import__(module)                #引入模块的名字
    # print(m.time())
    
    
    
    
    # 面向对象里的重点
    classmethod
    staticmethod
    property
    
    delattr
    hasattr
    getattr
    setattr
    
    isinstance
    issubclass
    
    object
    
    super
    
    
    # 了解
    # print(abs(-13))                         #取一个数的绝对值
    # print(all([1,2,3,'d']))                 #列表中的数的bool值均为True时,结果才为True
    # print(all([]))                          #all规定空列表的bool值为True
    
    # print(any([0,None,'',1]))                 #any 只要列表中的bool值有一个为True,整体的bool值就为True
    # print(any([0,None,'',0]))                 #any 列表中的所有bool值为False,整体的bool值就才为False
    # print(any([]))                            #any规定空列表的bool值为False
    
    # print(bin(3)) #11                         #将十进制转换为二进制
    # print(oct(9)) #11                         #将十进制转换为八进制
    # print(hex(17)) #11                        #将十进制转换为十六进制
    
    # print(callable(len))                      #检测对象是否可以被调用,可被调用指的是对象能否被()括号的方法
    
    # import time
    # print(dir(time))     #列举出所有:time.名字   #dir以列表的形式,列出time下的所用的方法
    
    
    # s=frozenset({1,2,3}) # 不可变集合,frozenset是冻结的集合,它是不可变的,存在哈希值,好处是它可以作为字典的key,也可以作为其它集合的元素。缺点是一旦创建便不能更改,没有add,remove方法。
    # s1=set({1,2,3})      # 可变集合,有add(),remove()等方法。既然是可变的,所以它不存在哈希值
    
    a=1111111111111111111111111111111111111111111111
    # print(globals())
    # print(locals())                 #此时站在全局和局部均有a值
    # def func():
    #     x=222222222
    #     print(globals())            #此时的全局仍然有'a': 1111111111111111111111111111111111111111111111, 'func': <function func at 0x0000015990572BF8>
    #     print(locals())             #此时站在局部只有{'x': 222222222}
    # func()
    
    # hash([1,2,3])                     #可变类型不可hash
    # hash(123)                         #不可变类型可以hash
    #
    # def func():
    #     """
    #     文档注释
    #     :return:
    #     """
    #     pass
    #
    # print(help(func))                 #help可以查看定义函数内的文档注释,
    
    # print(help(len))
    # print(help(max))
    
    
    l=['a','b','c','d','e']
    # s=slice(1,4,2)             #先拿到列表切片的范围
    # print(l[s])                #直接通过列表范围对列表进行切分
    # 等价于:
    # print(l[1:4:2])            #列表中去切片
    
    # print(vars())               #表示方差,用在算法中的numpy中
  • 相关阅读:
    美化博客园
    ansible的安装
    面向对象和类
    函数知识分类
    生成器
    内置函数_old
    迭代器
    装饰器
    Hadoop——MapReduce
    Hadoop——HDFS
  • 原文地址:https://www.cnblogs.com/sui776265233/p/9183773.html
Copyright © 2020-2023  润新知