浅说Python 中的函数式编程
函数式编程
函数式编程思想有着50多年的历史,最古老的算是Lisp语言了。如今众多语言都在一定程度上支持函数式编程,如Python、Ruby、Javascript,而其他一些语言如Java、PHP都增加了对于匿名函数的支持,可以看到函数编程的思想还很受欢迎。
下面一段话引自知乎,原文地址
函数式编程是一种编程范式,常见的编程范式有命令式编程,函数式编程,逻辑式编程,值得一提的是面向对象编程也是一种命令式编程。命令式编程是面向计算机硬件的抽象,有变量(对应着存储单元),赋值语句(获取及存储指令),表达式(内存引用和算术运算)和控制语句(跳转指令),总之,命令式程序就是一个冯诺依曼机的指令序列。而函数式编程是面向数学的抽象,将计算描述为一种表达式求值,一句话,函数式程序就是一个表达式。
函数式编程中的函数并不是指计算机中的函数,而是指数学中的函数,即自变量的映射,即一个函数的值仅决定于函数参数的值,不依赖其他状态。在函数式语言中,函数作为一等公民,可以在任何地方定义,可以作为函数的参数和返回值,可以对函数进行组合。纯函数式编程语言中的变量也不是命令式编程中的变量,即存储状态的单元,而是代数中的变量,即一个值的名称。变量的值是不可变的,即不允许像命令式编程语言中的那样多次给一个变量赋值。严格意义上的函数式编程意味着不使用可变的变量,赋值,循环和其他命令式控制结构进行编程。
函数式编程的好处
引用透明、没有副作用,用知乎上答主的说法就是
一个好处是,函数既不依赖外部的状态也不修改外部的状态,这使得单元测试和调试更加容易。另一个好处是由于多个线程间不共享状态,因而可以避免发生死锁,可以很好地实现并发。
除此以外,函数式语言还具有以下特性:
- 高阶函数(Higher-order function)
- 偏应用函数(Partially Applied Functions)
- 柯里化(Currying)
- 闭包(Closure)
Python 中的函数式编程
Python中对函数式编程语言的支持主要集中在提供了map(),reduce(),filter()三个函数和lambda算子,让人吃惊的是仅凭这几个函数就几乎可以实现任意的Python程序。
关于这几个函数的使用,参见我的另外一篇博客,上面有对这几个函数的介绍。
下面的内容参考自这个网址
替换条件控制语句
对于下面的条件控制语句
1
|
if condition1:
|
的结构,替换成下面的表达式
1
|
(condition1 and func1()) or (condition2 and func2()) or (func3())
|
下面是一个例子
1
|
|
可以看到采用这种方式可以实现条件控制的替换。
替换循环控制语句
-
替换for循环
由于和map函数使用相同,所以可以直接用map函数来实现for循环,看下面的例子1
2
3
4
5
6
7
8
9
10
11
12
13
14 -
替换while循环
相较而言,替换while循环稍稍麻烦一些,看下面的例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# statement-based while loop
while <condition>:
<pre-suite>
if <break_condition>:
break
else:
<suite>
# Equivalent FP-style recursive while loop
def while_block():
<pre-suite>
if <break_condition>:
return 1
else:
<suite>
return 0
while_FP = lambda: <condition> and (while_block() or while_FP())
while_FP()
函数式while_FP循环采用了递归的概念。当为true时,进入循环体,执行while_block();若为true时,返回1,while_FP()调用结束;若为false时,返回0,会继续执行or右侧的while_FP(),从而实现递归调用;若始终为false,则会持续递归调用while_FP(),这就实现了while语句中同样的功能。
看一个例子,下面的代码实现输入回显的echo功能,对比一下命令式编程和函数式编程。
1
|
#命令式编程版本
|
下面是函数式编程版本
1
|
def monadic_print(x):
|
再来看个例子,该例子实现找出笛卡尔积元组集合中元素之积大于25的所有元组。
1
|
bigmuls = lambda xs,ys: filter(lambda (x,y):x*y > 25, combine(xs,ys))
|

浙公网安备 33010602011771号