Python函数式编程之高阶函数

函数式编程,和面向对象编程一样,是现在很流行的一种编程范式。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值