大家好
这里还还还是长弓
今天我们来讲讲python中的函数式编程
目录
函数式编程
高阶函数
map
reduce
filter
sorted
返回函数
闭包
nonlocal使用
匿名函数lambda
装饰器
偏函数
有些同学疑惑了,我们已经学了函数,为什么还要学这个函数式编程呢?
两者的区别是什么呢?
函数是一个语法,函数式编程是一种编程的思路
是将本是CPU加减乘除的过程封装成一个个函数,调用函数的过程,更整体,更人性
函数式编程允许传入一个函数作为函数参数,返回值可以为一个函数
高阶函数
我们之前学习函数时,学习了很多很多类型参数,本质是将一个个变量传递到函数内部,那我们传一个特殊的变量,函数参数也是函数,即是高阶函数。
我们单独输入函数名得到结果和将函数名赋值给a得到相同结果,所以abs其实和a一样,只是一个指向函数本体的变量。过程如下图
明白了原理,我们动手写一个高阶函数(返回x三次方的绝对值)
map
map()是python内置的高阶函数,有两个参数,第一个是函数,第二个是可迭代对象。我们来看一下
reduce
上述map中返回的是类型是一个list(传啥回啥),如果我们想让返回原list中元素的和呢?
就要使用reduce(),也是传入两个参数
我们发现reduce返回的是一个整数,那上边的xy是什么呢?
第一次的x是1,y是2
第二次的x是3(1+2),y是3
依次循环,直到最后一个数据
这里需要注意,使用reduce需要从functools模块中导入
模块我们下一篇文章会细讲
filter
filter()函数和map函数类似,同样是返回一个可迭代对象
不同的是filter会通过条件筛选,只保留符合条件的元素
我们来实现一个filter,保存[1,2,3,4,5,6]中的偶数
我们观察,只有符合filter中函数的元素才会被返回
sorted
我们常需要数据是有序的,进而我们才可以下一步操作
sorted()函数就提供来排序的功能
一般需要排序的数据是整数和浮点数居多
不论是单独某类型还是两者混合都可以完成排序
可能有朋友疑惑了,这和高阶函数好像没啥关系吧?
对,因为这只是sorted的基础用法
它除了基础用法,也可以传函数作高阶函数
用法如下:
此时我们第一个函数参数传可迭代对象,第二是将功能函数abs赋值于key,这里的key名是固定的,不可变,否则会如上报错。
顺嘴一提,sorted同样可以对字符串类型进行排序(通过比较ASCIII码值大小,这里感兴趣同学可先自行查找资料),但目前了解即可。
返回函数
单纯返回一个函数是无用的,我们直接调用这个函数不就可以了吗
那这个功能的本质是什么呢?
我们来看下面的代码
这是一个求和函数,接下来我们定义一个later_sum函数,内部是我们上边的求和函数
我们看这个过程会发现很拧巴,且听我细细道来
- 1.我们创建later_sum,然后定义了函数sum,紧接着返回sum
- 2.我们调用later_sum,传入1,2,later_sum本身会调用sum函数
- 3.将执行完1,2相加的的sum返回,但此时为什么不是3呢?
因为返回的是函数本身,而不是执行结果,我们想要结果调用一下这个函数就输出了
(两个函数相套,内部函数可以使用外部函数的数据,这叫做“闭包”)
方便理解,函数套函数就是闭包
闭包
使用闭包时,我们不要内部使用for循环或while等循环语法,多次调用时可能会出现一些问题
使用循环会导致变量改变,而闭包只有在最后一刻才输出结果。因此我们期待的多个不同值输出,会统一输出为最后一次结果。
nonlocal使用
由于闭包概念存在,我们内部函数可以使用外部的数据,任意进行读取。
但当我们需要使用外部数据赋值的时候,就需要使用nonlocal语法了
先来看错误示范,会如下报错
修改一下
第一次失败的原因是因为虽然内部函数可以调用外部变量,但内部函数并没有进行初始化,就好像是男女朋友,但没结婚怀孕是不可以的,nonlocal就像是结婚的过程。
匿名函数lambda
目前为止,我们见到的每一个函数都是有名字的
但如果我们只是想实现一个简单的功能,能不能免除定义函数名称这样的步骤呢?
匿名函数可以实现
如倒数第五行,我们使用lambda将x+1赋予x,进而使用map函数list输出
当然我们也可以通过赋值给它一个名字
装饰器
装饰器,顾名思义起着装饰的作用,在实现主功能的基础上,我们实现附加功能装饰主功能。
(看到此图,建议过两天再回看,会完善的)
偏函数
偏函数是functools模块中的一个功能,它有什么用呢?
当函数参数确定过多时,选择太多越痛苦
偏函数就可以固函数参数数值,让我们不用选择
相当于设定默认参数,进而返回一个新函数
比如我们常用的int函数
默认是将字符串转化为十进制,第二个base参数也可以修改转化为几进制
上边报错是因为123不是二进制规范
如果我们有大量字符串数据需要转化为二进制,每次都写base未免太麻烦了
这是我们之前学的默认函数
偏函数可以简化这一过程
不仅感慨,开发者是真高效(懒)啊~
好了,今天的内容就到这里
我们下一篇主要讲解Python模块的使用
下次再见......