您的位置:首页 > 编程语言 > Python开发

Python函数式编程之高阶函数

2016-05-21 17:35 691 查看
函数式编程,和面向对象编程一样,是现在很流行的一种编程范式。

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

函数式编程最大的特点就是将函数看作是一等公民,也就是和其他数据类型、数据结构一样,函数也可以赋给一个变量,作为参数、传入其他函数,或者是作为其他函数的返回值。而将函数作为参数的函数我们称之为高阶函数

高阶函数

>>> f = abs
>>> f(-10)
10
>>> abs(-10)
10
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
abs(-10)
TypeError: 'int' object is not callable


从上面的代码可以看出,函数实际上是一个功能,任何一个变量可以指向一个函数,获得这个功能;而函数名是什么呢?函数名也是一个变量,只是这个变量初始指向了这个函数,当然也可以将这个变量指向其他值(实际上当然不能这么写);同时,一个变量,当然也可以作为参数传入函数啊,所以函数也可以作为参数传入其他函数

>>> def fun(x,y,p):
print(p(x,y))
>>> fun(2,3,pow)
8


这就是一个最简单的将函数作为参数传入参数的例子。在Python中有许多内置的高阶函数

map

map函数接收两个参数,一个func函数和一个Iterable对象。

func函数接收一个参数,将func函数作用于Iterable对象中的每一个元素,并返回一个map对象。

>>> def fun(x):
return x + 3

>>> map(fun, range(10))
<map object at 0x03234BD0>
>>> m = map(fun, range(10))
>>> isinstance(m,Iterator)
True
>>> list(m)
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]


从中可以看出,由于map对象也是一个Iterator,是一个懒惰序列,可以用list函数列出所有值。使用map对象可以对Iterable对象的每一个值进行函数操作,可以代替平时需要使用循环完成的功能

reduce

reduce函数接收两个参数:func函数和一个序列。其中的func函数接收两个参数,对序列中的值进行计算,并将结果与下一个值进行计算,直至产生最终结果

>>> from functools import reduce
>>> def add(x,y):
return x*10+y
>>> reduce(add,range(5))
1234


**map相当于对Iterable中元素逐一操作(str也能逐字符操作),reduce则能够将所有元素最终整合为一个结果。**map/reduce配合使用可以实现一些强大的功能

>>> def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(fn, map(char2num, s))

>>> str2int('12306')
12306


filter

filter函数的作用是筛选某一序列中符合条件的序列,接收一个func函数和一个序列

>>> def is_palindrome(n):
return str(n)==str(n)[::-1]
>>> output = filter(is_palindrome,range(1000))
>>> list(output)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99]


filter函数的重点在于构造用于判别元素是否符合条件的func函数!filter功能很强大,譬如下面的代码实现了一个输出素数的generator:

>>> def _odd_iter():
n = 1
while True:
n = n + 2
yield n
>>> def _div_fun(n):
def _div_check_fun(x):
return x % n > 0
return _div_check_fun
>>> def primes():
yield 2
iter = _odd_iter()
while True:
n = next(iter)
yield n
iter = filter(_div_fun(n), iter)#这里用到了闭包
>>> p = primes()
>>> next(p)
2
>>> next(p)
3
>>> next(p)
5


生成了一个懒惰计算的generator,然后就可以一个一个生成素数了!

sorted

sorted函数是一个排序函数

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']


sorted经常会有许多其他排序需求,这些就可以写一个排序函数,写入sorted函数的关键字参数key中

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']

>>> def fun(s):
return s[1].lower()
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=fun, reverse=True)
['Credit', 'bob', 'Zoo', 'about']


上面的例子,想要通过元素的第二个字母对list进行排序,那么传入的key参数函数中就应该返回第二个字母。

从上面的例子可以看出,高阶函数的抽象能力非常强大,能够使得代码保持简洁!

(By MrHammer 2016-05-21 下午5点 @Hohai Rainy)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: