函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
下面介绍一下函数式编程中常见的高阶函数:
map():
作用:
map()
函数接收两个参数,一个是函数,一个是Iterable(可迭代对象)
,map
将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator
返回。其效果如下:
map(f, [x1, x2, x3, x4]) = [f(x1), f(x2), f(x3), f(x4)]
举例:
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']:
def name(l_name): # 首字母大写,其它小写
l_name = l_name[0].upper() + l_name[1:].lower()
return l_name
l_name_1 = ['adam', 'LISA', 'barT']
l_name_2 = list(map(name, l_name_1)) # map让name函数对l_name_1进行递归处理
print(l_name_2) # ['Adam', 'Lisa', 'Bart']
相当于:
l_name_1 = ['adam', 'LISA', 'barT']
l_name_2 = []
for name in l_name_1:
name = name[0].upper() + name[1:].lower()
l_name_2.append(name)
print(l_name_2)
所以map()可以代替for循环。别看在这里for循环好像比map()用起来简单,当代码中有多个for循环嵌套时,map()在阅读速度上以及可维护性上都要比for循环好上许多
高阶函数多线程用法:
from multiprocessing.dummy import Pool # 进程池
def name(l_name):
l_name = l_name[0].upper() + l_name[1:].lower()
return l_name
pool = Pool(10) # 定义线程数
l_name_1 = ['adam', 'LISA', 'barT']
l_name_2 = pool.map(name, l_name_1)
print(l_name_2)
reduce():
作用:
reduce
把一个函数作用在一个序列[x1, x2, x3, ...]
上,这个函数必须接收两个参数,reduce
把结果继续和序列的下一个元素做累积计算。其效果如下:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
举例:
编写一个prod()函数,可以接受一个list并利用reduce()求积。输入:[3, 5, 7, 9],输出:945:
from functools import reduce # reduce在python2中是内置的,在python3中已移除,需要import
def prod(l):
return reduce(lambda x, y: x*y,l) # reduce让lambda创建的匿名函数对l进行两两递归处理
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
print('测试成功!')
else:
print('测试失败!')
# 输出:3 * 5 * 7 * 9 = 945 \n 测试成功!
filter():
作用:
和map()
类似,filter()
也接收一个函数和一个序列。不同的是,filter()
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
决定保留还是丢弃该元素。其效果如下:
filter(f, [x1, x2, x3, x4]) = [x1, x3, x4] # f(x1) = True, f(x2) = False, f(x3) = True, f(x4) = True
举例:
利用filter()函数把一个序列中的空字符串删掉:
def not_empty(s):
return s and s.strip()
print(list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))) # filter让not_empty函数对列表进行递归处理,并返回['A', 'B', 'C']
相当于:
s1 = ['A', '', 'B', None, 'C', ' ']
s2 = []
for e in s1:
if e != None:
if e.strip() != '':
s2.append(e)
else: pass
else: pass
print(s2)
map()可以代替for,同样的filter()也可以代替if-else,理由同上
sorted():
作用:
排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。其效果如下:
sorted(f, [x1, x2, x3, x4]) = [x4, x2, x3, x1] # f(x4) > f(x2) > f(x3) > f(x1)
举例:
用sorted()对列表中元组分别按名字进行排序:
l = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t): # 函数作用,取出元组中的第一个元素
return t[0]
L2 = sorted(l, key=by_name) # sorted让key指定的by_name函数对l进行递归处理,返回['Bob', 'Adam', 'Bart', 'Lisa'],之后再做排序
print(L2) # [('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
参考链接:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017434209254976