目录

函数式编程

首先要确定一点就是:函数 != 函数式,函数式编程是一种编程的范式。

特点:

  • 把计算视为函数而非指令
  • 纯函数式编程,不需要变量,没有副作用,测试简单
  • 支持高阶函数,代码简洁

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 进阶_函数式编程的更多相关文章

  1. Python进阶:函数式编程实例(附代码)

    Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...

  2. Python进阶之函数式编程(把函数作为参数)

    什么是函数式编程? 什么是函数式编程? 函数:function 函数式:functional,一种编程范式 函数式编程是一种抽象计算的编程模式 函数≠函数式,比如:计算≠计算机 在计算机当中,计算机硬 ...

  3. Python进阶之函数式编程

    函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...

  4. Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊

    函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...

  5. (转)Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)

    原文:https://www.cnblogs.com/chenwolong/p/reduce.html 函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数 ...

  6. day16_函数作用域_匿名函数_函数式编程_map_reduce_filter_(部分)内置函数

    20180729    补充部分代码 20180727    上传代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # ***************** ...

  7. Python Decorator 和函数式编程

    看到一篇翻译不错的文章,原文链接: Python Decorator 和函数式编程

  8. Python基础:函数式编程

    一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...

  9. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

随机推荐

  1. spring事务——try{...}catch{...}中事务不回滚的几种处理方式(转载)

    转载自   spring事务——try{...}catch{...}中事务不回滚的几种处理方式   当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @Respon ...

  2. Quartz-第一篇 认识Quartz

    1.什么是Quartz Quartz是一个任务调度框架,借助Cron表达式,Quartz可以支持各种复杂的任务调度.JDK中也提供了简单的任务调度,java.util.Timer. Quartz的三大 ...

  3. [BZOJ3626] [LNOI2014]LCA(树链剖分)

    [BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...

  4. Codeforces 1082D (贪心)

    题面 传送门 分析 贪心 将度限制大于1的点连成一条链,然后将度限制等于1的点挂上去 形状如下图,其中(1,2,3)为度数限制>1的点 显然直径长度=(度数限制>1的节点个数)-1+min ...

  5. [暑假集训Day3T1]小木棍

    经典搜索题. 考虑以下9种优化 1)按木棍长度排序,使得较大长度的木棍被较早的选出. 2)只找能够整除的木棍长度,因为不能被sum整除一定不会出整数根,自然也就不是最优解. 3)枚举木棍长度时只需从最 ...

  6. 攻防世界--re1

    练习文件下载:https://www.lanzous.com/i5lufub 1.使用IDA打开,进入main函数. 2.转为C代码 可以看到,输入v9之后,与v5比较,判断我们输入的flag是否正确 ...

  7. 【刷题】java 常见的几种运行时异常RuntimeException

    常见的几种罗列如下: -NullPointerException - 空指针引用异常 ClassCastException - 类型强制转换异常. IllegalArgumentException - ...

  8. winform中进行post上传文件

    winform中要上传文件到远程的服务器上面,我在本地用的是post方式传递数据,用的是HTTP协议,具体代码如下: 下面的代码就是一个上传的方法,参数需要路径和文件路径就可以了,我本地winform ...

  9. 利用delegate来解决类之间相互引用问题(引用死锁)

    类之间相互引用--类A中需要调用类B中的方法,同时,类B中又要调用类A中的方法.(也被称为引用死锁,通常会出现编译错误). 解决方法是,在类A中引用类B,并使类A成为类B的delegate,这样在类A ...

  10. c#同时验证手机号和座机号正则

    string strPatern2= @"(^(\d{3,4}-)?\d{6,8}$)"; string strPatern = @"(^1[3-8]\d{9}$|^\d ...