Python 函数式编程(map reduce filter sorted)
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 函数式编程(map reduce filter sorted)相关的知识,希望对你有一定的参考价值。
Python进阶
前言
函数是 Python 内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的 函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。 函数就是面向过程的程序设计的基本单元。
函数式编程
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。
而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一 个函数!
高阶函数
变量可以指向函数
以 Python 内置的求绝对值的函数 abs()为例:
print(abs(-10))
结果是:
10
但是如果只写 abs 会输出如下结果:
<built-in function abs>
可见,abs(-10)是函数调用,而 abs 是函数本身。要获得函数调用结果,我们可以把结果赋值给变量:
x = abs(-10)
x便是返回结果
把函数本身赋值给变量
f = abs
print(f)
最后x便指向abs函数
函数本身也可以赋值给变量,即:变量可以指向函数。如果一个变量指向了一个函数, 那么,可以通过该变量来调用这个函数。
函数名也是变量
函数名其实就是指向函数的变量!对于 abs()这个函数,完全可以把函数名 abs 看成变 量,它指向一个可以计算绝对值的函数。 如果把 abs 指向其他对象,示例如下:
abs = 10
print(abs(-10))
把 abs 指向 10 后,就无法通过 abs(-10)调用该函数了!因为 abs 这个变量已经不指向求绝对值函数了!
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数 作为参数,这种函数就称之为高阶函数。
高阶函数的示例
def add(x, y, f):
return f(x) + f(y)
print(add(-5, 6, abs))
当我们调用 **add(-5, 6, abs)**时,参数 x,y 和 f 分别接收-5,6 和 abs,根据函数定义,我们可以推导计算过程为:
x ==> -5
y ==> 6
f ==> abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。Python 内建的高阶函数有 map、reduce、filter、sorted。之后我会将分别介绍。
map
map()函数接收两个参数,一个是函数,一个是序列,map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 list 返回。
注意
- map():返回的是一个可迭代对象
# 使用 map 实现
it = map(f, a) # 返回的it是一个可迭代对象
- 判断是否是可迭代对象
isinstance(it, Iterator)
:判断是否是该类的实例对象的一种内置函数
# 导包
from collections import Iterator
print('判断是否是可迭代的:', isinstance(it, Iterator))
print(list(it))
map 实现将 list 所有数字开平方
比如我们有一个函数 f(x)=x2,要把这个函数作用在一个 list [1, 2, 3, 4, 5, 6, 7, 8, 9]上, 就可以用 map() 实现如下:
可能会想,不需要 map()函数,也可以计算出结果,写一个循环,实现代码如下:
- 原始 Python 代码实现
def f(x):
return x * x
L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
L.append(f(n))
print(L)
- map 实现
def f(x):
return x * x
L = map(f,[1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(L))
map 实现将 list 所有数字转为字符串
从上面的实例可以看到,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的 f(x)=x2,还可以计算任意复杂的函数。
比如,把这个 list 所有数字转为字符串,实例代码如下:
L = map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(L))
map 函数传入两个列表
计算两个列表的和,对应元素相加,返回新列表
def f2(x,y):
return x+y
L = map(f2, [1,2,3,4], [10,20,30])
print(list(L))
结果如下
reduce
reduce 把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f( f( f(x1, x2), x3), x4)
- 首先需要导包
from functools import reduce
reduce实现序列快速求和
对一个序列求和,就可以用 reduce 实现,实例如下:
from functools import reduce
def add(x, y):
return x + y
sum = reduce(add, [1, 3, 5, 7, 9])
print(sum)
reduce实现序列变整数
如果想把序列[1, 3, 5, 7, 9]变换成整数 13579。将列表中的每个元素乘以 10 加上后一个元素。
def fn(x, y):
return x * 10 + y
a = reduce(fn, [1, 3, 5, 7, 9])
print("reduce 执行结果:",a)
filter
Python 内建的 filter()函数用于过滤序列。
- 和 map()类似,filter()也接收一个函数和一个序列。
- 和 map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
filter 过滤列表,删掉偶数,只保留奇数
在一个 list 中,删掉偶数,只保留奇数。
def isOdd(n):
return n % 2 == 0
x = [2, 3, 4, 5]
y = filter(isOdd, x)
print(list(y))
filter 序列中的空字符串删掉
# 删除空字符串
a = ['A', '', None, 'C', ' ']
def not_empty(s):
return s and s.strip() # strip()去除首尾空白
l = filter(not_empty, a)
print(list(l))
sorted
排序算法,排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。
如果是数字,我们可以直接比较,但如果是字符串或者两个 dict 呢?
直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。
通常规定,对于两个元素 x 和 y,如果认为 x < y,则返回-1,如果认为 x == y,则返回 0, 如果认为 x > y,则返回 1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。
sorted 对 list 进行排序
# 对数值进行排序,默认升序
sort_list = sorted([42, 422, 4, 2, -100])
print(sort_list)
sorted 对 list 自定义的排序
sorted()函数也是一个高阶函数,它还可以接收一个 key 函数来实现自定义的排序
默认是升序排序
降序
传参
reverse=True
# 逆序
sort_list = sorted([42, 422, 4, 2, -100], reverse=True)
序列绝对值后排序
sorter2 = sorted([1,3,6,-20,-70],key=abs)
print("自定义排序:",sorter2)
绝对值+反向排序
key=abs,reverse=True
sorter2 = sorted([1,3,6,-20,-70],key=abs,reverse=True)
print("自定义反向排序:",sorter2)
字符串ASCII码 排序
# 4.2 字符串排序依照 ASCII sorter3 = sorted(["ABC","abc","D","d"]) print("字符串排序:",sorter3)
忽略大小写排序
key = str.lower
sorter4 = sorted(["ABC","abc","D","d"],key=str.lower)
print("忽略字符串大小写排序:",sorter4)
#要进行反向排序,不必改动 key 函数,可以传入第三个参数
reverse=True:
sorter5=sorted(["ABC","abc","D","d"],key=str.lower,reverse=True)
print("忽略字符串大小写反向排序:",sorter5)
参考或摘自尚学堂的PDF,感谢!
站在巨人的肩膀上前进
加油!
以上是关于Python 函数式编程(map reduce filter sorted)的主要内容,如果未能解决你的问题,请参考以下文章