Python学习之函数式编程

Linux编程

点击右侧关注,免费入门到精通!

作者丨stone_zhu

https://www.jianshu.com/p/efa8925e0256

高阶函数

在python中函数名是指向函数的变量,当函数的参数也是函数的时候,这种函数我们称之为高阶函数。

map/reduce

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

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

结合map和reduce可以整理出一个str2int的函数:

filter

Python内建的filter()函数用于过滤序列。

和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

例如,在一个list中,删掉偶数,只保留奇数,可以这么写:

sorted

对list进行排序:

此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

字符串排序:

忽略大小写:

要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True

返回函数

定义

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:

但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数:

当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:

调用函数f时,才真正计算求和的结果

闭包

如上所示的例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”。

注意点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如下所示:

返回结果如下:

匿名函数

关键字lambda表示匿名函数,冒号前面的x表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

装饰器

代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数。

定义一个能打印日志的decorator,可以定义如下:

观察上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:

把@log放到now()函数的定义处,相当于执行了语句:now = log(now),now变量指向了新的函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

这个3层嵌套的decorator用法如下:

和两层嵌套的decorator相比,3层嵌套的效果是这样的:>>> now = log('execute')(now)

有个问题,经过decorator装饰之后的函数,它们的name已经从原来的'now'变成了'wrapper':

Python内置的functools.wraps用来复制函数name属性的:

或者针对带参数的装饰器:

偏函数

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

创建偏函数时,实际上可以接收函数对象、args和*kw这3个参数。

比如要使用int()函数去转换二进制字符串,原本的写法是:int(x, base=2),如果量大的话,很麻烦,所以我们可以这么写:

上面的in2 = functools.partial(int, base=2)相当于:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181017B1WYTA00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券