13-01高阶函数
目录
明确目的(本章知识点)
- 什么是高阶函数
- 实例-方便理解函数是如何作为参数或者返回值的
- 函数作为参数的场景
- 函数作为返回值的场景
- 函数即作为参数又作为返回值的场景
- python内置3个高阶函数-map、filter、reduce
模拟教学(尝试讲清楚)
1、什么是高阶函数
- 有一个函数,它的参数是函数
- 有一个函数,它的返回值是函数
- 有一个函数,它的参数和返回值都是函数
- 如上三个函数,都是高阶函数。一句话总结就是:(参数是函数)或者(返回值是函数)的函数,就是高阶函数。
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、函数作为参数的场景
- 先来个简单的例子理解理解
如下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,先实现最基本的功能,默认是逆序
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]
- 部分总结
- 使用高阶函数的方式可以少写很多代码。也就是说写代码可以不用高阶函数(会造成代码量多逻辑复杂)
- 函数作为参数:通常用于大多数逻辑固定,少部分逻辑不固定的场景。
- python内置了一个排序函数
sorted()
,就是典型的函数作为参数的函数
4、函数作为返回值的场景
- 先来个简单的例子理解理解
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
-
实际应用中的场景,比如
经验不够,编不出来 -
部分总结
函数作为返回值:通常是用于闭包的场景,需要封装一些变量
5. 函数即作为参数又作为返回值的场景
装饰器:它的参数是一个函数,返回值也是一个函数。
那么可以说,所有的装饰器都是高阶函数的一种,理解了装饰器就理解了此知识点
详见装饰器篇
6. python内置3个高阶函数-map、filter、reduce
经验不够,编不出来
重复回顾(老占位行)
- 用纸写出
本章知识点
- 问问自己该知识点有哪些没理解透彻
- 如果理解透彻就将概念简化
- 如果不可以,重新
模拟教学
概念简化(把知识点简化成一两句话)
- 什么是高阶函数,为什么要用高阶函数
(参数是函数)或者(返回值是函数)的函数,就是高阶函数。
使用高阶函数少些很多代码,优化业务代码逻辑。 - 理解函数是如何作为参数或者返回值
函数fn, 不调用时是一个python函数对象, fn()调用时就是一个函数
- 函数作为参数的场景
通常用于大多数逻辑固定,少部分逻辑不固定的场景。经验不够,编不出来
- 函数作为返回值的场景
通常是用于闭包的场景,需要封装一些变量。经验不够,编不出来闭包是什么暂时不知道
- 函数即作为参数又作为返回值的场景
装饰器的时候再深入理解
- python内置3个高阶函数-map、filter、reduce
三个函数分别用来做什么。经验不够,编不出来