13-01高阶函数

明确目的(本章知识点)

  1. 什么是高阶函数
  2. 实例-方便理解函数是如何作为参数或者返回值的
  3. 函数作为参数的场景
  4. 函数作为返回值的场景
  5. 函数即作为参数又作为返回值的场景
  6. python内置3个高阶函数-map、filter、reduce

模拟教学(尝试讲清楚)

1、什么是高阶函数

  1. 有一个函数,它的参数是函数
  2. 有一个函数,它的返回值是函数
  3. 有一个函数,它的参数和返回值都是函数
  4. 如上三个函数,都是高阶函数。一句话总结就是:(参数是函数)或者(返回值是函数)的函数,就是高阶函数。

2、实例-方便理解函数是如何作为参数或者返回值的

廖雪峰大神写得非常好,我就直接复制整理过来了。

以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码:

>>> abs(-10)
10

但是,如果只写abs呢?

>>> abs
<built-in function abs>

可见,abs(-10)是函数调用,而abs是函数本身。

要获得函数调用结果,我们可以把结果赋值给变量:

>>> x = abs(-10)
>>> x
10

但是,如果把函数本身赋值给变量呢?

>>> f = abs
>>> f
<built-in function abs>

结论:函数本身也可以赋值给变量,即:变量可以指向函数。

如果一个变量指向了一个函数,那么,可否通过该变量来调用这个函数?用代码验证一下:

>>> f = abs
>>> f(-10)
10

成功!说明变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。

3、函数作为参数的场景

  1. 先来个简单的例子理解理解

如下add函数就是高阶函数,f就是一个函数

In [156]: def add(x, y, f):
...: return f(x) + f(y)
...:
In [157]: add(-5, 6, abs) 
Out[157]: 11
  1. 实际应用中的场景,比如排序算法
    需求:写一个函数,传入一个列表。并对列表的值进行排序
例1:实现版本1,先实现最基本的功能,默认是逆序
In [178]: def sort(it): 
     ...:     ret = [] 
     ...:     for x in it: 
     ...:         for i, e in enumerate(ret): 
     ...:             if x > e: 
     ...:                 ret.insert(i, x) 
     ...:                 break 
     ...:         else: 
     ...:             ret.append(x) 
     ...:     return ret 

In [179]: sort([1, 2, 34, 6, 8, 5])
Out[179]: [34, 8, 6, 5, 2, 1]

例2:例1中只支持顺序排序,如果我要顺序排序呢,是否又要重写一个呢,来个版本2的,当r为True时就是顺序了
In [180]: def sort(it, r=False): 
     ...:     ret = [] 
     ...:     for x in it: 
     ...:         for i, e in enumerate(ret): 
     ...:             if r: 
     ...:                 if x < e: 
     ...:                     ret.insert(i, x) 
     ...:                     break 
     ...:             else: 
     ...:                 if x > e: 
     ...:                     ret.insert(i, x) 
     ...:                     break 
     ...:         else: 
     ...:             ret.append(x) 
     ...:     return ret 

In [25]: sort([38, 99, 24, 44, 18])
Out[25]: [99, 44, 38, 24, 18]

In [26]: sort([38, 99, 24, 44, 18], r=True)
Out[26]: [18, 24, 38, 44, 99]

例3:功能上要少写重复代码,不然一旦修改则要修改2处,改进版3
In [181]: def sort(it, r=False): 
     ...:     ret = [] 
     ...:     def cmp(a, b): 
     ...:         if r: 
     ...:             return x < e 
     ...:         else: 
     ...:             return x > e 
     ...:
     ...:     for x in it: 
     ...:         for i, e in enumerate(ret): 
     ...:             if cmp(x, e): 
     ...:                 ret.insert(i, x)     # 对比例2,当要修改,本实例只需要修改一次
     ...:                 break 
     ...:         else: 
     ...:             ret.append(x) 
     ...:     return ret 

例4:使用高阶函数来写该函数,lambda是匿名函数(单行函数)
In [38]: def sort(it, cmp=lambda a, b: a < b):
    ...:     ret = []
    ...:     for x in it:
    ...:         for i, e in enumerate(ret):
    ...:             if cmp(x, e):
    ...:                 ret.insert(i, x)
    ...:                 break
    ...:         else:
    ...:             ret.append(x)
    ...:     return ret
    ...:

In [39]: sort([1, 2, 34, 6, 8, 5])
Out[39]: [1, 2, 5, 6, 8, 34]

In [40]: sort([1, 2, 34, 6, 8, 5], lambda a, b: a > b)
Out[40]: [34, 8, 6, 5, 2, 1]
  1. 部分总结
    1. 使用高阶函数的方式可以少写很多代码。也就是说写代码可以不用高阶函数(会造成代码量多逻辑复杂)
    2. 函数作为参数:通常用于大多数逻辑固定,少部分逻辑不固定的场景。
    3. python内置了一个排序函数sorted(),就是典型的函数作为参数的函数

4、函数作为返回值的场景

  1. 先来个简单的例子理解理解
In [12]: def build(x, y):
    ...:     def tmp_der():         # 定义一个函数
    ...:         return x * y
    ...:     return tmp_der         # return把这个函数作为结果返回
    ...:

In [13]: f = build(3, 5)        # 把return赋值给了f,return的是一个函数, f的值也是一个函数

In [14]: f         # f的值,python一切皆对象,函数也是一个对象
Out[14]: <function __main__.build.<locals>.tmp_der()>

In [15]: f()      # 既然是函数那么就可以调用,f()调用一下就有结果了
Out[15]: 15
  1. 实际应用中的场景,比如
    经验不够,编不出来

  2. 部分总结
    函数作为返回值:通常是用于闭包的场景,需要封装一些变量

5. 函数即作为参数又作为返回值的场景

装饰器:它的参数是一个函数,返回值也是一个函数。
那么可以说,所有的装饰器都是高阶函数的一种,理解了装饰器就理解了此知识点

详见装饰器篇

6. python内置3个高阶函数-map、filter、reduce

经验不够,编不出来

重复回顾(老占位行)

  1. 用纸写出本章知识点
  2. 问问自己该知识点有哪些没理解透彻
  3. 如果理解透彻就将概念简化
  4. 如果不可以,重新模拟教学

概念简化(把知识点简化成一两句话)

  1. 什么是高阶函数,为什么要用高阶函数

    (参数是函数)或者(返回值是函数)的函数,就是高阶函数。
    使用高阶函数少些很多代码,优化业务代码逻辑。

  2. 理解函数是如何作为参数或者返回值

    函数fn, 不调用时是一个python函数对象, fn()调用时就是一个函数

  3. 函数作为参数的场景

    通常用于大多数逻辑固定,少部分逻辑不固定的场景。经验不够,编不出来

  4. 函数作为返回值的场景

    通常是用于闭包的场景,需要封装一些变量。经验不够,编不出来闭包是什么暂时不知道

  5. 函数即作为参数又作为返回值的场景

    装饰器的时候再深入理解

  6. python内置3个高阶函数-map、filter、reduce

    三个函数分别用来做什么。经验不够,编不出来

posted @ 2020-11-05 18:24  此时  阅读(96)  评论(0编辑  收藏  举报