Python之函数式编程和高阶函数(map、reduce、filter、sorted)

Echo ·
更新时间:2024-11-10
· 958 次阅读

目录

函数式编程

函数的本质:

高阶函数:

内置高阶函数

map:

reduce:

filter:

sorted:

函数式编程

首先来看一段函数式编程的定义,不想看的先跳过,结合具体实例后再来理解吧!

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有 变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数。 其实,学习函数式编程可以简化我们的代码量,有些功能一行搞定! 函数的本质:

函数本质上也是一个变量,既然是变量,那么就可以进行赋值操作。将函数变量赋值给另一个普通变量,那么可以通过'普通变量()'形式来调用函数。

来看个例子,使用Python内置函数abs()求绝对值,运行结果是10。变量a就指向了abs函数,可以通过'普通变量()'来调用。

a = abs # 把函数本身赋值给变量 print(a(-10)) # 通过变量来调用函数

因此,通过这个例子可以看出来,函数名其实就是指向函数的变量!对于abs() 函数,就可以把abs看成指向计算绝对值函数的变量。

再来看个例子,变量命名为内置函数名会发生什么。 abs = 6 print(abs(-5))

可以看到计算绝对值函数功能失效了,因为abs不指向计算绝对值函数了,这也解释了大家在最初学习Python命名时,强调的变量名不要和Python内置的名字重名。 因此,函数本质上还是一个变量!既然是变量,那么可不可以将函数传入另一个函数呢?肯定可以啊! 高阶函数:

高阶函数的概念:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

自定义高阶函数: 来看个函数作为变量传递给另一个函数的例子。

def add(x,y,f): return f(x)+f(y) # "普通变量()的形式" print(add(-5,-6,abs)) # 计算绝对值

结果是11。

内置高阶函数 有了自定义高阶函数,那么来看看Python内置的高阶函数,它是Python开发者编写好的方法,肯定比我们普通人写的更加完善,用起来更加方便。 map: map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

 map部分源码, 来看几个例子,理解map的使用。

比如我们有一个函数 f(x)=x2,要把这个函数作用在一个 list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用 map()实现如下:

用普通函数实现上图的需求:

def f(x): return x*x ls = [1,2,3,4,5,6,7,8,9] map_ls = [] for i in ls: map_ls.append(f(i)) print(map_ls)

用高阶函数map实现:

def f(x): return x * x ls = [1, 2, 3, 4, 5, 6, 7, 8, 9] map_ls = map(f, ls) print(list(map_ls)) # map类型,转成list类型

 用map+lambda来实现:这里也体现了Python代码的简洁性。

map_ls = map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) print(list(map_ls))

再来看个例子,map实现将list所有数字转为字符串,借助了内置函数str。

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

运行结果:['1', '2', '3', '4', '5', '6', '7', '8', '9']

我们可以注意到map源码map(func, *iterables),第二个参数表示可以传递多个变量。

最后再来看个传入两个列表的例子,计算两个列表相应位置元素之和。

def f(x, y): return x + y map_ls = map(f, [1, 2, 3, 4], [5, 6, 7]) print(list(map_ls))

运行结果:[6, 8, 10]

reduce:

reduce的作用是把一个函数作用在一个序列[x1,x2,x3...],每次作用的结果继续和序列下一个元素做累积计算。

作用效果如下:

注意使用reduce时,需要导入包,只有这个特殊一些。

用reduce实现累加: from functools import reduce def add(x, y): return x + y total = reduce(add, [1, 3, 5, 7, 9]) print(total)

结果:25

再来看一个小例子,如何把序列[1,2,3,4,5]变成整数12345,可以每个元素乘以10再加上后一个元素。

from functools import reduce def f(x,y): return x*10 + y total1 = reduce(f,[1,2,3,4,5]) # 还可以一行代码实现这个功能 total2 = reduce(lambda x,y:x*10 + y,[1,2,3,4,5]) print(total1) # 12345 print(total2) # 12345 filter:

filter单词意思为“过滤”,实际上filter函数就是对数据过滤,比如我们一列数字中,我们只需要偶数,就需要把奇数过滤掉。

filter也是接收一个函数和一个序列,然后把每个元素作用在函数上,根据返回值是True还是False决定保留元素还是删除元素。 我们就以去掉序列中的奇数为例,来看个例子。 def is_odd(n): return n % 2 == 0 ls = filter(is_odd,[1,2,3,4,5,6]) print(list(ls)) # 这里和map函数类似,也需要转换类型

运行结果:[2, 4, 6]

再来看个例子,如何去掉序列中的空字符串,注意:''和‘     ’这两种形式

# 在处理空字符串时,要注意下面两种形式的区别 a = '' # False b = ' ' # True , 用strip()来转成False if a: # False print("hello") # 不走这里 if b: # True print("world") # 走这里,但是它是空字符串,我们需要借助strip()函数来去掉空格

运行结果:world

def not_empty(s): return s and s.strip() ls = filter(not_empty,['adfsd','','2',' ']) print(list(ls))

运行结果:['adfsd', '2'] 

sorted: sort相信大家学习过数据结果或者其他编程语言时,一定会遇到这个单词‘排序’。排序算法光常用的就有8中,但是不论什么排序算法核心都会涉及到比较两个元素大小。 比较大小:比较数字的话,直接比大小即可。但是比较字符串或者字典的话,再按照数字比较法是没什么意义的,因此我们需要自己根据实际需求来定义比较字符串或字典的规则,这时我们就可以使用Python内置的sorted函数来制定规则。字典比较的key其实也是字符串。 通常规定,对于两个元素x和y,如果xy,return 1;这个不是硬性规定,但是一般都默认这种写法。 sorted在使用的时候,可以不传递函数,默认升序排列。也可以传递参数,传递的参数根据源码来看。 源码:__iterable:传递要排序的序列;key:绑定函数;reverse:升序还是降序

还是老套路,看几个例子,来理解高阶函数用法。 第一个例子,对数字列表进行排序 sort1 = sorted([20,30,-100,-5,8,9]) # 升序 print(sort1) # [-100, -5, 8, 9, 20, 30] sort2 = sorted([20,30,-100,-5,8,9],reverse=True) # 降序 print(sort2) # [30, 20, 9, 8, -5, -100] sort3 = sorted([20,30,-100,-5,8,9],key=abs) # 按照绝对值升序 print(sort3) # [-5, 8, 9, 20, 30, -100] sort4 = sorted([20,30,-100,-5,8,9],key=abs,reverse=True) # 按照绝对值降序 print(sort4) # [-100, 30, 20, 9, 8, -5]

第二个例子,对字符串排序,根据ASCII码。

常用ASCII码值:a=97,A=65

sort1 = sorted(['adfsd','abc','AB','Ab','fgb']) # 升序 print(sort1) # ['AB', 'Ab', 'abc', 'adfsd', 'fgb'] sort2 = sorted(['adfsd','abc','AB','Ab','fgb'],key=str.lower) # 忽略大小写升序排列 print(sort2) # ['AB', 'Ab', 'abc', 'adfsd', 'fgb'] sort3 = sorted(['adfsd','abc','AB','Ab','fgb'],key=str.lower,reverse=True) # 忽略大小写降序 print(sort3) # ['fgb', 'adfsd', 'abc', 'AB', 'Ab']

到这里简单的四个高阶函数就学完了,要注意的使用这些函数是否要导入包呀,传递参数的位置呀等等,大家要学着看源码哦!


作者:听~当



reduce filter sorted map 函数 函数式编程 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号