参考:https://coolshell.cn/articles/10822.html https://www.imooc.com/learn/317
用过python的闭包,装饰器,map,reduce,filter等函数,也知道可以把一个函数作为一个变量进行赋值,传递;但是还不知道这些都属于函数式编程的范畴,也一直以为这些都是理所当然的,当然,去区分我们写的程序是函数式编程的范畴还是过程式编程的范畴并不重要,而是理解它的思想,把这种思想运用到平时的项目中去。最近读了陈皓老师的博客,看了廖雪峰老师的python进阶教程,将一些python的函数式编程做一个总结。后续项目中如果有更深的体会,再更新。
目录
一.python的函数式编程的特点
1.不是纯函数式编程,允许有变量
2.支持高阶函数,函数可以作为变量传入一个函数
3.支持闭包,函数可以作为另一个函数的返回值
4.支持匿名函数
二.高阶函数
1.变量可以指向一个函数
# 变量可以指向一个函数
f = abs # 此时f指向python的内建函数abs
print(f(-3)) # 输出3
2.函数名其实是指向函数的一个变量,函数名和普通的变量没有什么区别
# 函数名其实是指向函数的一个变量
abs = len # abs指向len函数
print(abs([1, 2, 3, 4])) # 输出4
print(abs(-3)) # 程序报错
3.高阶函数是指可以接收函数作为参数的函数
# 高阶函数是指可以接收函数作为参数的函数
def add(x, y, f):
return f(x) + f(y)
print(add(1, -3, abs)) #输出4
三.Python内置的高阶函数
1.map函数
原理:map函数接收一个函数f,和一个可迭代的数据类型如list,将函数f依次作用在list中的每个元素,最终得到一个新的list迭代器并返回,但是不改变原list
举例:将列表中每个人名的首字母大写,其他小写
def transer_name(s):
'''姓名转换函数'''
return s[0].upper() + s[1:].lower()
namelist = ['AyA', 'aDAm', 'imp'] # 原姓名列表
new_name = map(transer_name, namelist) # 新姓名列表迭代器
for name in new_name:
print(name) # 打印结果:Aya Adam Imp
2.reduce函数
原理,reduce函数接收一个函数f,和一个可迭代的数据类型如list,
函数f必须接收两个参数,每次接收list中的两个元素,并将返回值作为下一次传参的第一个参数,返回最终的结果。
如计算一个列表的元素之和
# 如计算一个列表的元素之和 两个参数
from functools import reduce # python3中reduce需要从functools中导入
def add(x, y):
return x + y
alist = [1, 2, 3, 4, 5]
print(reduce(add, alist)) # 输出15
函数f也可以接收三个参数,第一个参数是函数f,第二个参数是一个可迭代的对象,第三个对象是计算的初始值,对于上述例子,如果将计算的初始值设为100,那么输出结果为115
# 如计算一个列表的元素之和 三个参数
from functools import reduce # python3中reduce需要从functools中导入
def add(x, y):
return x + y
alist = [1, 2, 3, 4, 5]
print(reduce(add, alist, 100)) # 输出115
3.filter函数
原理:filter函数接收一个函数f,和一个可迭代的数据类型如list,函数f作用于list的每一个元素,并对结果进行True or False的判断,若结果False,则过滤掉list中的该元素,返回一个新的list。
举例:从一个列表中过滤出偶数
# 从一个列表中过滤出偶数
def filter_ov(num):
return num % 2 == 0
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 旧list
new_list = filter(filter_ov, alist) # 新list迭代器[2,4,6,8]
for num in new_list:
print(num)
4.sorted函数,自定义排序
原理:sorted函数排序默认按照从小到大的顺序排序,若要实现倒序排序,可以接收一个reversed参数,reversed参数默认为Fasle,若传入True,表示倒序排序。sorted函数可以接收一个key参数,key参数可以是一个函数,表示排序规则,如下所示:
# 按照字典的值正序排序
adict = {1: 'abc', 3: 'kjdq', 2: 'qcnkve'}
print(sorted(adict.items(), key=lambda x: x[1])) # 输出[(1, 'abc'), (3, 'kjdq'), (2, 'qcnkve')]
# 按照字典的键倒序排序
print(sorted(adict.items(), key=lambda x: x[0], reverse=True)) #输出[(3, 'kjdq'), (2, 'qcnkve'), (1, 'abc')]
四.函数作为返回值&闭包
1.函数作为一个函数的返回值
python的函数不仅可以返回int,str等常用的数据类型,还可以返回函数;但是需要注意的是,返回函数时返回的是函数名inner,而不是inner(),这两者是完全不一样的。返回函数可以把一些计算延迟
# 函数作为一个函数的返回值
def out():
def inner():
print('inner')
return inner
f = out()
print(f) # 输出:<function out.<locals>.inner at 0x0000021DD8F647B8>
f() # 输出:inner
2.闭包
闭包是【函数作为返回值】的一种特殊情况,闭包中内函数引用了外函数的变量,然后返回内函数。要正确使用闭包,需确保引用的外层函数局部变量再函数返回后不会在变化。
举例:一次返回三个函数,分别计算1*1,2*2,3*3
# 一次返回三个函数,分别计算1*1,2*2,3*3
def out():
f_list = []
for i in range(1, 4):
def inner(j):
def g():
return j * j
return g
r = inner(i)
f_list.append(r)
return f_list
f1, f2, f3 = out()
print(f1()) # 1
print(f2()) # 4
print(f3()) # 9
五.匿名函数
https://blog.youkuaiyun.com/lincoco49/article/details/89365293
六.装饰器
https://blog.youkuaiyun.com/lincoco49/article/details/89552500