zoukankan      html  css  js  c++  java
  • 匿名函数python内置高阶函数以及递归

    匿名函数

    python定义一个函数通常使用def关键词,后面跟函数名,然后是注释、代码块等。

    def func():
        '''注释'''
        print('from func')
    

    这样就在全局命名空间定义了一个叫func的函数,func表示函数体的内存地址,因为func指向函数体内存地址,所以可以通过func来调用函数。

    那么匿名函数呢?从名字就可看出,匿名。想想就有点像以前小时候的佚名一样,带点说不清楚的神秘色彩,现在想来之所以感觉神秘可能是因为那时候不认识‘’佚‘’这个字。。。

    强调:
        匿名函数的定义就相当于只产生一个变量在值,而没有绑定任何名字,
        所以会在定义完之后就被回收,无法重复使用,只能在定义时使用一次
    应用:当某一个功能仅使用一次就没有再重复使用的必要了,就应该定义成匿名函数
    

    言归正传,匿名和佚名一样没有名字或者不需要知道名字,对就是这么酷。

    定义一个匿名函数使用lambda关键词,和def比较的话会发现其实定义逻辑很像。

    lambda x: x**2
    

    定义的匿名函数的意思是参数为x,返回x的平方,返回?怎么没看到return?因为lambd引号后面的值默认返回,所以没必要加return了,但是我一定要加呢?就是这么不讲道理。那么解释器只好报错了,因为你不认同我的语法,那我也没必要惯着你了。就是这么拽。

    匿名函数的使用场景通常为使用一次就结束了,不会频繁的使用。而且匿名函数通常和python里面自带的高阶函数结合使用,在某些应用场景下会达到事倍功半的效果哦。

    高阶函数

    map

    map的意思是地图的意思,由此引申出映射表示一一对应。

    翻译过来的意思是:创建一个迭代器,使用每个迭代的参数计算函数。 当最短的可迭代用尽时停止。

    map函数有两个参数,第一个为某种规则的函数,第二个位多个可迭代对象。

    def func(x):
        return x * 2
    lis = [1, 2, 3, 4, 5, 6]
    print(type(map(func, lis)))
    print(list(map(func, lis)))
    

    map函数把可迭代对象中的元素自动传给func,通过func的加工,得到一个生成器对象,通过list函数转化为一个列表。

    当然,map函数可以接收多个可迭代对象,比如

    def func(x, y):
        return x + y
    lis1 = [1,2,3,4,5,6]
    lis2 = [2,3,4,5,6,7,8,9,10,11]
    print(list(map(func, lis1,lis2)))
    # 结果为[3, 5, 7, 9, 11, 13]
    

    map函数会把后面迭代器对象中的元素迭代出来经过func加工,当最短的可迭代用尽是停止,所以只进行到6+7就结束了。

    reduce

    reduce是减少、合并的意思,会把可迭代对象中的元素经过函数的加工进而产生新的结果。

    翻译过来就是:从左到右累加两个参数的函数到序列的项目,以便将序列减少为单个值。例如,reduce(lambda x,y:x + y,[1,2,3] ,4,5]计算(((((1 + 2)+3)+4)+5)。如果存在初始值,则将其放置在计算中序列的项之前,并在序列为空时用作默认值。

    reduce函数有三个参数,函数和序列都是必须参数,初始值为可选参数。

    应用:比如求1-100的和

    from functools import reduce
    def func(x, y):
        return x+y
    print(reduce(func, [i for i in range(1,101)]))
    # 结果为 5050
    

    filter

    filter的意思为过滤,通过函数的返回值对序列进行过滤。

    翻译过来:返回一个迭代器,产生函数(item)为真的迭代项。 如果函数为None,则返回结果为真的项。

    def func(x):
        return x.isdigit()
    lis = ['12', 'ad', '34', 'bc', '46']
    print(list(filter(func, lis)))
    # 结果为 ['12', '34', '46']
    

    filter过滤结果为真的值放进迭代器中。

    高阶函数和匿名函数

    map和匿名函数

    在之前map函数中的func参数都是定义了一个有名参数,然后用函数名传入map函数的,有了匿名函数就不用这么麻烦了。

    lis = [1, 2, 3, 4, 5, 6]
    print(list(map(lambda x: x*2, lis)))
    # 结果为 [2, 4, 6, 8, 10, 12]
    

    reduce和匿名函数

    print(reduce(lambda x, y: x + y, [i for i in range(101)], 100))
    # 输出结果为 5050
    

    filter和匿名函数

    sala = {
         'MAC': 30000,
         'iPhone': 9000,
         'lenovo': 10000,
         'xiaomi': 3000
    }
    print(list(filter(lambda x: sala[x] > 5000, sala)))
    # 输出结果为 [‘iPhone', 'lenovo']
    

    匿名函数的使用场景较为单一,一次性使用,随用随时定义。在某些场景下和高阶函数结合会提升效率,同时使代码更加简洁。

    递归

    一 递归调用的定义

    递归调用时函数嵌套调用的一种特殊形式,函数在调用时,直接或间接地调用了自身,就是递归调用。

    # 直接调用自身
    def f1():
        print('from f1')
        f1()
    f1()
    
    # 间接调用自身
    def f1():
        print('from f1')
        f2()
    
    
    def f2():
        print('from f1')
        f1()
    f2()
    
    # 调用函数会产生局部的名称空间,占用内存,因为上述这种调用会无限调用自身,python解释器的内存管理机制为了防止无限占用内存,对函数的递归调用做了层级限制,可以通过代码修改最大层级限制。
    import sys
    sys.setrecursionlimit(100000)
    

    二 递归调用的两个阶段

    递归调用包含两个明确的阶段:回溯,递推

    • 回溯就是从外向里一层一层递归调用下去,回溯阶段必须要有一个明确的结束条件(不然会成为死循环),每进入下一次递归时,问题的规模都应该有所减少。

    • 递推就是从里向外一层层结束递归。

    • 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈实现的,每当进入一个函数调用,在栈下面会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用次数过多,会导致栈溢出)

    三 二分法

    从一个排序的数字列表中找到指定的数字,使用遍历的效率太低,使用二分法可以极大地缩小问题规模。

    1. 实现in的效果

      nums = [1,5,12,23,34,46,59,99,443]
      
      def fucn(num, nums):
          if len(nums) == 0:
              return
          mid_index = len(nums) // 2
          if num > nums[mid_index]:
              nums = nums[mid_index+1:]
              fucn(num, nums)
      
          elif num < nums[mid_index]:
              nums = nums[:mid_index]
              fucn(num,nums)
          else:
              print('not exis')
      
    2. 实现index的效果

      nums = [1, 13, 15, 23, 27, 31, 33, 57, 73, 81, 93, 94, 97, 101]  # 从小到大排列的数字列表
      def binary_search(find_num,nums):
          print(nums)
          if len(nums) == 0:
              print('not exists')
              return
      
          # 功能
          mid_index = len(nums) // 2
          if find_num > nums[mid_index]:
              # in the right
              nums=nums[mid_index+1:]
              # 重新运行功能,传入新列表
              binary_search(find_num,nums)
          elif find_num < nums[mid_index]:
              # in the left
              nums=nums[:mid_index]
              # 重新运行功能,传入新列表
              binary_search(find_num,nums)
          else:
              print('find it')
              
      binary_search(95,nums)
      
  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/zuanzuan/p/9768972.html
Copyright © 2011-2022 走看看