Python高阶函数

高阶函数(经常简称为HOFs)就是以一个或多个函数为参考并返回一个函数的函数。

>>>x=abs(-10)

这样是我们常见的方式,把函数的调用结果,赋值给变量

其实python还可以支持把函数赋值给变量

>>>f=abs

>>>f(-10)

说明变量f指向了abs函数本身,直接调用abs()函数和调用f()一样

那么什么是高阶函数呢:

def add(a,b,f)

return f(a)+f(b)

即把一个函数作为参数,这种函数称为高阶函数,我们可以想一下,函数的参数一般意义上来说,应该是变量。但是函数又能赋值给变量,因此函数也就可以作为参数调用。

a=”abc”

b=”efg”

f=upper

return f(a)+f(b) 等价于 upper(“abc”)+upper(“efg”)   等价于 “ABCEFG”

python中一些有用的高阶函数包含在functools中,而另一些则是内建的。

通常认为map(),filter()以及functools.reduce()是python中高阶函数的基础模块。

内建函数map()与filter()与解析式(comprehension)等价(尤其是考虑到目前生成器解析式(generator comprehension)已经可用),但是很多python程序员认为解析式可读性更强一些。例如,以下表达式是等价的:

 

python 高阶函数例子 python高阶函数指什么_python

 

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

>>>list(map(str,[1,2,3,4,5,6,7,8,9]))

[‘1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’]

python 高阶函数例子 python高阶函数指什么_python_02

函数functools.reduce()非常通用,强大但是想发挥其全部威力的技巧却相当微妙。它以前后相继的迭代器对象为参数,并以某种方式将它们结合起来。reduce()最常见的用法可能已经由内建函数sum()涵盖了,sum()函数实际上只是以下形式的简写:

 

python 高阶函数例子 python高阶函数指什么_赋值_03

reduce把一个函数作用在一个序列[x1,x2,x3…]上,让这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累计计算,其效果就是:

reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)

因此上述表达式就十分好理解了。

现在引入一个概念lambda函数:

如果我们要做两个数的加和,一般的写法为

def sum(x,y):

return x+y

如果我们用lambda来实现:

p=lambda x,y:x+y

print(p(4,6))

匿名函数lambda:是指一类无需定义函数名的函数或子程序

lambda函数可以接收任意多个参数(包含可选参数)并且返回单个表达式的值

注意:lambda函数不能包含命令,包含的表达式不能超过一个

那么,我们还可以用lambda函数来进一步简化操作:

reduce(lambda x,y : x*10+y , [100,99,98,97])

reduce第一个函数表达式,必须接收2个参数。

其次reduce还可以接收一个缺省的初始化值,比如:

f= lambda x,y :x+y

reduce(f, [1, 3, 5, 7, 9], 100)

正常的计算逻辑是:

先计算头两个元素:f(1, 3),结果为4;

再把结果和第3个元素计算:f(4, 5),结果为9;

再把结果和第4个元素计算:f(9, 7),结果为16;

再把结果和第5个元素计算:f(16, 9),结果为25;

由于没有更多的元素了,计算结束,返回结果25。

但是有一个初始化的值,那在最开始的一步计算就应该为f(100,1)

因此最后的答案应该为125。

>>> add5 = lambda n: n+5

>>> reduce(lambda l,x: l+[add5(x)],range(10),[])

[5,6,7,8,9,10,11,12,13,14]

>>> # simpler: map(add5,range(10)

>>> isOdd = lambda n: n%2

>>> reduce(lambda l,x: l+[x]if isOdd(x) else l, range(10),[])

[1,3,5,7,9]

>>> # simpler: filter(isOdd,range(10))

这个就比较好理解了,一个空数据,加上一个只有一个5元素的数组,就会形成一个5的数组,依次增加,为什么说reduce强大,reduce可以替代map及filter函数。

这些reduce()表达式令人困惑,但是它们说明了这个函数具有多么强大的通用性:任何对前后相继元素的计算都可以表达为reduce()的形式。

而filter就是指对参数进行过滤

和map()类似,filter()也接收一个函数和一个序列。与map()不同的是,filter()把函数作用在每个元素后,根据返回的布尔类型,决定是保留还是舍弃元素。

例如:

filter(lambda n : n%2==1,range(10))

也有一些常用的高阶函数不包含在python的原始库中,但是它们可以通常容易编写 (并且有些第三方库包含了这些函数)。不用的库以及不同的语言可能使用不同的函数名称,但是它们都拥有类似的功能。在具体的使用过程中,可以详细去研究。