高阶函数
2021-7-5
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property

 

变量可以指向函数

Python内置的求绝对值的函数abs()为例:
函数本身也可以赋值给变量,即变量可以指向函数
 
 

函数名也是变量

那么函数名是什么呢?函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数!
如果把abs指向其他对象,会有什么情况发生?
无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数而是指向一个整数10
当然实际代码绝对不能这么写。
 

传入函数

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
一个最简单的高阶函数:
调用add(-5, 6, abs)时,参数xyf分别接收-56abs,根据函数定义,可以推导计算过程为:
 

map

map()函数接收两个参数,一个是函数,一个是Iterablemap将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
比如函数,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,可以用map()实现如下:
notion image
由于结果r是一个IteratorIterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
 
不需要map()函数,写一个循环,也可以计算出结果,但是并不直观:
 
所以,map()作为高阶函数,事实上它把运算规则抽象了,因此不但可以计算简单的 ,还可以计算任意复杂的函数,比如把list所有数字转为字符串:
 

reduce

reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
 
对一个序列求和,就可以用reduce实现:
 
当然求和运算可以直接用内建函数sum(),没必要动用reduce。但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579reduce就可以派上用场:
 
考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),就可以写出把str转换为int的函数:
 
整理成一个str2int的函数就是:
 
还可以用lambda函数进一步简化成:
也就是说,假设Python没有提供int()函数,完全可以自己写一个把字符串转化为整数的函数,而且只需要几行代码!
 
 
例题:利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']
 
例题:Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:
 
例题:利用mapreduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456
 
 

filter

Python内建的filter()函数用于过滤序列。
map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
 
把一个序列中的空字符串删掉,可以这么写:
可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。
注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list
 
用filter求素数
计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:
  • 首先,列出从2开始的所有自然数,构造一个序列:2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
  • 取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
  • 取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:5, 6, 7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...
  • 取新序列的第一个数5,然后用5把序列的5的倍数筛掉:7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...
  • 不断筛下去,就可以得到所有的素数
 
 

sorted

sorted()函数也是一个高阶函数
  • Python
  • 生成器和迭代器返回函数
    目录