zoukankan      html  css  js  c++  java
  • 18.python高阶函数

    什么是高阶函数:一个函数可以作为参数传给另外一个函数(一个函数可以用来接收另一个函数作为参数),或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),满足其一则为高阶函数。函数的形参位置必须接受一个函数对象。

    代码理解高阶函数的含义:

     1 '''函数当做参数被传递到另个函数是什么样的。把abs()函数赋值给了f变量,接下来就可以像使用abs()函数本身那样使用f变量了,区别只是换了个名字而已'''
     2 
     3 f = abs           # 将求绝对值的abs函数赋值给f变量
     4 f(-123)           # f变量等同于abs函数的功能和性质,区别只是换了个别名
     5 print(f(-123))    # 输出结果 123
     6 print(type(f))    # <builtin_function_or_method>  查看下这个f变量的类型,显示为内置函数,因为它的真身就是内置abs()函数
     7 
    8 '''这说明变量可以指向函数,既然变量可以指向函数,而我们知道函数的参数可以接收变量。也就是说一个函数可以接收另一个函数作为参数,一起来看看下面这个例子''' 9 def add_(a, b, f_): 10 return f_(a) + f_(b) # 在本例中等同于 abs(a) + abs(b) 11 12 result = add_(-10, -20, abs) # 这里把python内置函数abs作为参数传递给add_ 13 print(result) # 30

    代码演示高阶函数两种场景:

     1 # 高阶函数之 ---》参数为函数
     2 def bar():
     3     print("in the bar..")
     4 def foo(func):
     5     func()
     6     print("in the foo..")
     7 
     8 foo(bar)
     9 
    10 
    11 # 高阶函数之 ---》返回值为函数
    12 def bar():
    13     print("in the bar..")
    14 def foo(func):
    15     print("in the foo..")
    16     return bar
    17 res=foo(bar)
    18 res()
    19 
    20 '''以上两个示例中,函数foo()为高阶函数。示例一中函数bar作为foo的参数传入;示例二中函数bar作为foo的返回值。
    注意:函数名(例如bar 、foo)-->其为该函数的内存地址;函数名+括号(例如 bar()、foo() )-->调用该函数
    '''

    python里的高阶函数有 filter、map、reduce、sorted、匿名函数lambda,递归函数等。

    1). map函数

    功能:map函数接收的是两个参数,接收一个函数 f 和一个或多个序列list,其功能是将序列中的值处理再依次返回至新列表内,其返回值为一个迭代器对象。

    语法格式:map(function, iterable,[iterable1, ...iterablen])

    参数:(1).function: 函数对象 ;(2).iterable:序列(可迭代)对象 (字符串、列表、range...)

    返回值:得到的这个map对象是一个迭代器对象,属于惰性序列的范畴。

    代码演示map实现原理:

     1 # 需求:将lt = ['1','2','3','4','5'] 转换成  [1,2,3,4,5]
     2 
     3 # 代码实现一:使用传统技术来实现
     4 lt = ['1','2','3','4','5','6']
     5 lt1 = []
     6 for i in lt:
     7     num = int(i)
     8     lt1.append(num)
     9 print(lt1)     # [1, 2, 3, 4, 5, 6] 由于列表属于非惰性序列范畴,即可以直接打印看效果
    10  
    11 
    12 # 代码实现二:使用新技术来实现
    13 # 思路步骤一:定义一个函数,功能:将str数据 --> int数据
    14 import collections
    15 lt = ['1','2','3','4','5','6']
    16 def chr2Int(chr): 17 return int(chr) 18 19 mo = map(chr2Int,lt) # 这里的chr2Int后面不能加(),也不能传参***** 20 print(map,type(mo)) # <class 'map'> <class 'map'> 21 print(isinstance(mo,collections.Iterator)) # True,验证是否是迭代器对象,True才能使用next 22 print(next(mo)) # 1 23 print(list(mo)) # [2, 3, 4, 5, 6] 将map对象(惰性的)转换为list对象(非惰性的) 24 25 26 #代码实现三:终极操作 27 print(list(map(chr2Int,lt))) #[1, 2, 3, 4, 5, 6] 28 print(list(map(int,lt)) #[1, 2, 3, 4, 5, 6] 29 30 '''map(int,lt):执行过程如下: 31 1).lt --> 取出第一个元素:'1'当做实际参数传递给int函数的形参位置 --> int('1'),将转换以后的结果:1保留到map对象的第一个元素位置 32 2).lt --> 取出第二个元素:'2'当做实际参数传递给int函数的形参位置 --> int('2'),将转换以后的结果:2保留到map对象的第二个元素位置 33 以此类推... 34 直到map函数执行完了,整个map对象才真正成型了...'''

    代码演示示例:

     1 # 实例1: lt = [1,2,3,4,5] --> 得到:['1','2','3','4','5']
     2 
     3 lt = [1,2,3,4,5]
     4 
     5 # 自定义函数:从int --》 str
     6 def int2Str(i):
     7     return str(i)
     8 
     9 print(list(map(int2Str,lt)))                  # ['1', '2', '3', '4', '5']
    10 print(list(map(str,lt)))                      # ['1', '2', '3', '4', '5']
    11 print(list(map(lambda x: str(x),lt)))         # ['1', '2', '3', '4', '5']
    12  
    13 
    14 # 实例2:lt = [1,2,3,4,5] --> 得到:[1,4,9,16,25]
    15 
    16 lt = [1,2,3,4,5]
    17 
    18 # 自定义函数:目标实现开方操作
    19 def kaifang(num):
    20     return num ** 2
    21 
    22 print(list(map(kaifang,lt)))                     # [1, 4, 9, 16, 25]
    23 print(list(map(lambda x: x ** 2,lt)))            # [1, 4, 9, 16, 25],map结合匿名函数使用,用的比较多


    2).reduce函数

    功能:reduce函数也是一个参数为函数,一个为可迭代(序列)对象的高阶函数,但reduce()传入的函数必须接收两个参数,reduce()对list的每个元素反复调用函数function。所以reduce()函数接收的参数和 map()类似,但是行为不同。reduce() 函数会对参数序列中元素进行累积,其返回值为一个值而不是迭代器对象,故其常用与叠加、叠乘等。

    语法格式:reduce(function, iterable[, iterable1,...,iterablen] [, initializer])

    参数:function -- 函数,有两个参数。iterable -- 可迭代对象。initializer -- 可选,初始参数

    返回值:为一个值,而不是迭代器对象

    【注意】:reduce函数属于functools模块中的函数,所以需要显示的先导入functools模块再使用from functools import reduce

    代码演示reduce实现原理:

     1 from functools import reduce
     2 
     3 '''当调用reduce(f,[1,3,5,7,9])时,reduce函数将做如下计算:由于f这个函数的功能是计算两个元素的值,所以先计算头两个元素:f(1,3),
     4    结果为4;再把结果和第3个元素计算:f(4,5),结果为9;再把结果和第4个元素计算:f(9,7),结果为16;
     5    再把结果和第5个元素计算:f(16,9),结果为25;由于没有更多的元素了,计算结束,返回结果25。'''
     6 def f(x, y):
     7      return x + y
     8  
     9 result = reduce(f, [1, 3, 5, 7, 9])
    10 print(result)   # 25
    11 
    12 
    13 '''reduce()**还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为100,如计算:结果将变为125,
    因为第一轮计算是:计算初始值和第一个元素:f(100, 1),结果为101。
    ''' 14 reduce(f, [1, 3, 5, 7, 9], 100) 15 16 17 # 使用 lambda 匿名函数 18 reduce(lambda x, y: x+y, [1,3,5,7,9])
     1 '''reduce函数执行顺序:先将lsd中的第一和第二个元素传入到fn中参与运算,运算后得到结果,再和第三个元素传入到fn中参与运算,以此类推...'''
     2 
     3 # 需求:得到元祖tp = (1,2,3,4)中元素的和值
     4 
     5 '''首先自定义函数 --> add作用:对列表中的元素进行求和操作 def add(x,y)
     6 然后使用reduce函数执行过程如下:
     7 第一次:add(1,2)
     8 第二次:add(add(1,2),3)
     9 第三次:add(add(add(1,2),3),4)'''
    10 
    11 # 代码实现一:递归的思想来实现
    12 tp = (1,2,3,4)
    13 def mySum(num):
    14     if num == 1:
    15         return 1
    16     return num + mySum(num - 1)
    17 
    18 print(mySum(4))
    19 
    20 
    21 # 代码实现二:reduce函数实现
    22 from functools import reduce
    23 def add(x,y):
    24     return x + y
    25 
    26 res = reduce(add,tp)
    27 
    28 print(res,type(res))                 # 10 <class 'int'>
    29 print(reduce(lambda x,y: x + y,tp))  # 10
    30 print(sum(tp))                       # 10 直接使用内置函数sum()了

    代码演示示例:

     1 # 实例1:lt = [1,2,3,4] 得到其中元素的乘积
     2 
     3 lt = [1,2,3,4]
     4 print(reduce(lambda x,y: x * y,lt))
     5  
     6 # 实例2:从键盘读入一个整数字符串数据,例如:'12345',将其转换为12345;
     7 '''注意:不能直接使用int()来实现.思路:使用map和reduce配合来实现
     8 步骤一:'12345' --》拆分为散装数据:1 2 3 4 5    可以使用map来实现
     9 步骤二:将map对象中的数据 1 2 3 4 5 组合成为 --> 12345    可以使用reduce来实现
    10 '''
    11 from functools import reduce
    12 
    13 str1 = '12345'
    14 def chr2Int(str):
    15     return int(str)
    16 
    17 def zuhe(x,y):
    18     return x * 10 + y
    19 
    20 mo = map(chr2Int,str1)
    21 num = reduce(zuhe,mo)
    22 print(num,type(num))          #12345 <class 'int'>
    23 
    24 
    25 #终极版:
    26 print(reduce(lambda x,y: x * 10 + y,map(int,str1)))         #12345 
    
    

    3).filter函数

    功能:filter()函数也是接收两个参数,接收一个函数和一个序列的高阶函数,其主要功能是过滤,过滤掉不符合条件的元素,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新序列中。filter的意思:在计算机领域中我们都称为过滤器。

    语法格式:filter(function, iterable)

    参数:和map、reduce一样理解,function:判断函数,iterable :可迭代对象。

    返回值:一个惰性序列对象(filter对象,迭代器对象),例如列表

    代码演示示例:

     1 # 示例1:lt = [1,2,3,4,5,6,7,8] --> 得到:[2,4,6,8]
     2 
     3 lt = [1,2,3,4,5,6,7,8] 
     4 #代码实现一:老技术
     5 lt1 = []
     6 for i in lt:
     7     if i % 2 == 0:
     8         lt1.append(i)
     9 
    10 print(lt1)
    11 
    12 
    13 #代码实现二:新技术(filter)
    14 def func(o):
    15     if o % 2 == 0:
    16         return True
    17     return False
    18  
    19 fo =filter(func,lt)
    20 
    21 print(fo,type(fo))  #<filter object at 0x0000000001E8F710> <class 'filter'>
    22 print(list(filter(func,lt)))           #[2, 4, 6, 8]
    23 print(isinstance(fo,collections.Iterator))     #Ture
    24 print(isinstance(fo,collections.Iterable))     #Ture
    25 print(next(fo))                #2
    26 print(next(fo))                #4
    27 print(list(fo))                  #[6, 8]
    28  
    29 
    30 # 终极版:
    31 print(list(filter(lambda x:x % 2 == 0,lt)))    #[2, 4, 6, 8]
    32  
    33 
    34 # 示例2:lt = [345,0,'abcde',1.2,0,3.14,0.0,'haha','hehe',True,False,[],(),{},{1,2,3},[10,20,30],{'name':'zs','age':30},None]
    35 得到如下效果:lt = [345,'abcde',1.2,3.14,'haha','hehe',True,{1,2,3},[10,20,30],{'name':'zs','age':30}]
    36 
    37 lt = [345,0,'abcde',1.2,0,3.14,0.0,'haha','hehe',True,False,[]
    38 ,(),{},{1,2,3},[10,20,30],{'name':'zs','age':30},None]
    39 
    40 print(list(filter(lambda x: bool(x),lt)))
    41 #或者
    42 print(list(filter(bool,lt)))
    43 
    44 
    45 # 示例3:lt1 = ['aaaaaaaa','bbbbb','cccccc','ddd']得到如下效果:['aaaaaaaa','cccccc']
    46 
    47 lt1 = ['aaaaaaaa','bbbbb','cccccc','ddd']
    48 
    49 print(list(filter(lambda x: len(x) > 5,lt1)))


    高阶函数以及匿名函数之间的配合使用(练习):

     1 '''模板一:lambda和filter的配合使用'''
     2 # 需求:lt = [1,2,3,4,5,6,7,8,9] --> 得到[3,6,9]
     3 
     4 print(list(filter(lambda x: x % 3 == 0,lt)))
     5 
     6 
     7 '''模板二:lambda 和map的配合使用'''
     8 # 需求:演示开平方操作  --> 容器对象:range
     9 
    10 mo = map(lambda x: x ** 2,range(5))
    11 print(list(mo))
    12 
    13 
    14 '''模板三:在模板二的基础上进行功能扩展:range(10),过滤以后保留的数据范围大小为:(5,50)之间'''
    15 
    16 mo = map(lambda x: x ** 2,range(10))
    17 fo = filter(lambda x: x > 5 and x < 50,mo)
    18 print(list(fo))
    19 
    20 
    21 '''模板四:lambda 和reduce配合使用'''
    22 # 求和值
    23 import functools
    24 
    25 lt = [1,2,3,4,5]
    26 
    27 my_sum = functools.reduce(lambda x,y: x + y,lt)
    28 print(my_sum)
    29 
    30 
    31 '''模板五:求两个列表对象中元素的和,返回新列表:
    32 lt1 = [1,2,3,4], lt2 = [5,6,7,8], 结果:lt3 = [6,8,10,12]'''
    33 
    34 mo = map(lambda x,y: x + y,lt1,lt2)
    35 print(list(mo))
    36 
    37 
    38 '''模板六:求字符串中每个单词的长度content = "welcome to shanghai", 结果:[7,2,8]'''
    40 # 使用切割的思想:切完之后得到一个列表对象,内部元素["welcome","to","shanghai"]
    41 words_list = content.split()
    42 mo = map(len,words_list)
    43 print(list(mo))

  • 相关阅读:
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四)
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(一)
    MSCRM Plugin Debug
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(二)
    [转].net 使用NPOI或MyXls把DataTable导出到Excel
    HTML5的十大新特性
    语义化的HTML及其目的
    XHTML和HTML有什么区别
    浏览器根对象document之方法概述
    浏览器根对象document之数值和布尔属性
  • 原文地址:https://www.cnblogs.com/bonheur/p/12374412.html
Copyright © 2011-2022 走看看