Python 进阶_函数式编程
目录
函数式编程
首先要确定一点就是:函数 != 函数式,函数式编程是一种编程的范式。
特点:
- 把计算视为函数而非指令
- 纯函数式编程,不需要变量,没有副作用,测试简单
- 支持高阶函数,代码简洁
Python 函数式编程的特点
需要注意的是,Python 不是也不可能会成为一种纯函数是编程语言,但 Python 仍支持许多有价值的函数式编程语言的构建方法。
- Python 不是纯函数是编程,因为 Python 支持变量
- Python 支持高阶函数,而且函数也可以作为变量传入
- Python 支持闭包,可以返回一个函数
高阶函数
首先要明确一点,函数是由变量来引用的,这也是一个 Python 的特性:将对象引用和对象分离。
EG:
In [1]: abs(-1)
Out[1]: 1
In [2]: f = abs # 将函数名赋值给一个变量,让变量获得函数的引用
In [3]: f(-1)
Out[3]: 1
In [5]: abs = len
In [6]: abs([1, 2, 3])
Out[6]: 3
高阶函数: 能够接收函数作为一个参数的函数,就是高阶函数。
下面定义一个高阶函数:
In [1]: def add(x, y, f):
...: return f(x) + f(y)
...:
In [2]: add(-1, -10, abs)
Out[2]: 11
函数 add 接收内建函数 abs 作为一个参数,所以 add 是一个高阶函数。
匿名函数 lambda
格式:
lamba [arg1[, arg2, ...]]: expression # --> return: object of function
匿名函数,顾名思义就是没有名字的函数,可以忽略函数定义的函数。所以匿名函数的好处之一就是创建简易、方便,不需要以标准的定义方式(def)来创建。而且匿名函数可以如一般函数那样返回一个 callable 的函数对象,所以匿名函数一般会赋值给一个变量,或者直接作为一个函数实参来使用。从匿名函数的语法格式来看,其缺点也很明显,就是其函数体只能是一条 expression 而不能是一条关键字语句,如:print
NOTE: 因为匿名函数可以快速的返回一个函数对象,并且可以直接作为一个函数的实参使用,所以匿名函数经常被用于构建函数式的编程中。
EXAMPLE:
In [4]: def add(x, y):
...: return x + y
...:
In [5]: lambda x, y: x + y
Out[5]: <function __main__.<lambda>> # 返回一个可调用的函数对象
In [6]: lam_add= lambda x, y: x + y
In [7]: lam_add(1, 2)
Out[7]: 3
上面两种方式的结果是一致的。
注意: 如果 lambda 返回的对象没有赋值给一个变量,那么这个函数对象的引用 == 0,会被垃圾回收掉。
函数式编程相关的内置函数
Python 提供了几个与函数式编程相关的内置函数,之所以说与函数式编程相关是因为这几个内置函数都需要接收一个函数对象作为参数,而这个函数对象通常由 lambda 来提供。
filter() 序列对象过滤器
让序列对象中的每一个元素都通过一个指定的过滤器,最终符合过滤条件(Return True)的元素会被返回为一个新的序列。
要自己实现一个 filter 函数,并不难。EG.
def filter(bool_func, seq):
filtered_seq = []
for index in seq:
if bool_func(index):
filtered_seq.append()
return filtered_seq
EXAMPLE 1:求偶数
In [13]: filter(lambda x: x % 2 == 0, range(1,10))
Out[13]: [2, 4, 6, 8]
EXAMPLE 2:删除 None 或者空字符串
In [14]: def is_not_empty(s):
...: return s and len(s.strip()) > 0
...:
In [15]: filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
Out[15]: ['test', 'str', 'END']``
注意: 传入 filter 的函数最终的返回值一定是 True or False
map()
map 和 filter 很类似,但 map 函数通过把函数参数依次作用在 seq 的每个元素上,得到一个新的 seq 并返回。而且 map 的函数参数不要求一定要返回 True or False 。除此之外, map 还能处理多个序列参数。
def map(func, seq):
maped_seq = []
for index in seq:
maped_seq.append(func(index))
return maped_seq
EXAMPLE 1:处理单个序列对象
In [17]: map(lambda x :x+2, range(1,10))
Out[17]: [3, 4, 5, 6, 7, 8, 9, 10, 11]
EXAMPLE 2:处理多个序列对象
In [24]: map(lambda x, y :x + y, range(1,10), range(1,10))
Out[24]: [2, 4, 6, 8, 10, 12, 14, 16, 18]
注意:如果传递多个序列对象给 map 时,其处理的算法如下
1. 并行的将多个序列中 index 相同的元素获取,并捆绑到同一个元组中
2. 将这一个元组传递给函数参数中进行处理。
所以需要注意的是,两个序列的元素个数是否一致,函数参数是否能正确的处理这个元组对象
In [26]: map(None, range(1,6), range(1,6))
Out[26]: [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
In [27]: zip(range(1,6), range(1,6))
Out[27]: [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]`
从这个例子可以看出 map 可以完成一个简单的 zip 功能,这是由其内部的实现算法决定的。
reduce() 折叠
reduce 需要传入一个 二元函数(具有两个形参的函数) 、一个序列对象和一个可选的 初始化器。
其最常用的例子就是 累加:
In [28]: reduce(add, range(1, 100))
Out[28]: 4950
In [35]: reduce(add, range(1, 100), 5000)
# 初始化器 == 5000,即从 5000 开始累加
Out[35]: 9950
等效于:reduce(func, [1, 2, 3]) ⇒ func(func(1, 2), 3)
自定义的排序函数
Python 内置了一个排序函数 sorted
In [1]: sorted([36, 5, 12, 9, 21])
Out[1]: [5, 9, 12, 21, 36]
时 sorted 也是一个高阶函数,它可以接收一个比较函数来实现自定义排序。。
比较函数的定义是:传入两个待比较的元素 x, y
1. 如果 x 应该排在 y 的前面,返回 -1
2. 如果 x 应该排在 y 的后面,返回 1
3. 如果 x 和 y 相等,返回 0
所以我们可以自定义一个比较函数,并且传递给 sorted 函数:
In [3]: def reversed_cmp(x, y):
...: if x > y:
...: return -1
...: if x < y:
...: return 1
...: return 0
...:
In [4]: sorted([36, 5, 12, 9, 21], reversed_cmp)
...: [36, 21, 12, 9, 5]
...:
Out[4]: [36, 21, 12, 9, 5]
最后
本篇给出了一些内置高阶函数的例子,其实在编程中使用得更多的是自定义的高价函数,其中 闭包 就是一种非常常用的函数式编程。
Python 进阶_函数式编程的更多相关文章
- Python进阶:函数式编程实例(附代码)
Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...
- Python进阶之函数式编程(把函数作为参数)
什么是函数式编程? 什么是函数式编程? 函数:function 函数式:functional,一种编程范式 函数式编程是一种抽象计算的编程模式 函数≠函数式,比如:计算≠计算机 在计算机当中,计算机硬 ...
- Python进阶之函数式编程
函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...
- Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊
函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...
- (转)Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)
原文:https://www.cnblogs.com/chenwolong/p/reduce.html 函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数 ...
- day16_函数作用域_匿名函数_函数式编程_map_reduce_filter_(部分)内置函数
20180729 补充部分代码 20180727 上传代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # ***************** ...
- Python Decorator 和函数式编程
看到一篇翻译不错的文章,原文链接: Python Decorator 和函数式编程
- Python基础:函数式编程
一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...
- python学习_数据处理编程实例(二)
在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...
随机推荐
- Throwable -抛出异常类与自定义异常类
/* 自定义异常类 java提供的异常类,不够我们使用,需要自己定义一些异常类 格式: public class XXXException extends Exception/runtimeExcep ...
- JavaScript.convertArray
function convertArray(nodeList){ var arr = [] if(Array.prototype.slice){ arr = [].sl ...
- python获取ip地址
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import socket,fcntl,struct #crontab下shell命令无 ...
- Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)
题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...
- Ajax爬取豆瓣电影目录(Python)
下面的分析相当于一个框架,搞懂之后,对于类似的文字爬取,我们也可以实现.就算不能使用Ajax方法,我们也能够使用相同思想去爬取我们想要的数据. 豆瓣电影排行榜分析 网址:https://movie.d ...
- mysql02---客户端与服务器模型
目录 一.客户端与服务器模型 连接MySQL方式 总结: 二.MySQL服务器构成 三.MySQL的结构 一.客户端与服务器模型 1.mysql是一个典型的C/S服务结构 1.1 mysql自带的客户 ...
- 牛客小白月赛16 D 小阳买水果 (思维题)
链接:https://ac.nowcoder.com/acm/contest/949/D来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- k8s阅读笔记1-云原生
前言 阅读书籍地址https://rootsongjc.gitbooks.io/kubernetes-handbook/content/cloud-native/cloud-native-defini ...
- phpstorm ftp不能连接服务器
环境: ubuntu phpstorm 问题一. 服务器ftp功能没有开启 解决方法:在服务器上安装 ftp 服务 https://i.cnblogs.com/EditPosts.aspx?posti ...
- CF240E Road Repairs
最小树形图+输出方案 输出方案的话记录一下哪些边 然后记得最后拆环要倒着拆就行了