Python学习(四)—— 函数式编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1449516487/article/details/86528084

一、高阶函数

所谓高阶函数,是指将可以将函数作为参数传入的函数。

如:将abs()函数当做参数传入add()函数

>>> def add(x, y, f):
...     return f(x) + f(y)
...
>>> print(add(-5, 6, abs))
11

以下介绍Python内置的高阶函数:

(1)map函数

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator(Iterator是惰性序列,因此需通过list()函数计算整个序列并返回一个list)返回。例如计算一个式子f(x)=x^2,代入的x值为1~9。如下:

>>> def f(x):
...    return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 8, 16, 25, 36, 49, 64, 81]

(2)reduce函数

reduce()函数与map()函数类似,也接收一个函数和一个序列,不同的是reduce()函数把结果继续和Iterable的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

例如把序列[1, 3, 5, 7, 9]变换成整数13579,如:

>>> from functools import reduce
>>> def fn(x, y):
...    return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

(3)filter()函数

filter()函数接受一个函数和一个序列,用于过滤序列,把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

例如,在一个list中,删掉偶数,只保留奇数:

>>> def is_odd(n):
...    return n % 2 == 1
...
>>> list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
1
5
9
15

(4)sorted()函数

Python内置的sorted()函数可以对list进行排序:

>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]

此外,sorted()函数也是一个高阶函数,可以接受一个key函数来实现自定义的排序,例如按绝对值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

二、返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果返回,如:

>>> def lazy_sum(*args):
...    def sum():
...        ax = 0
...        for n in args:
...            ax = ax + n
...        return ax
...    return sum
...
>>> f = lazy_sum(1,3,5,7,9)   //lazy_sum()函数返回的是求和函数,并赋值给f
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>
>>> f()                       //只有当调用f()函数时,才会返回求和结果
25

三、匿名函数

匿名函数用关键字lambda表示,冒号前面的x表示函数参数,只能有一个表达式,并且不能写return,返回值就是该表达式的结果。形如:

lambda x: x * x

匿名函数也是一个函数对象,可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25

也可以把匿名函数作为返回值返回,例如:

def build(x, y):
    return lambda: x * x + y * y

四、装饰器

装饰器(Decorator)的作用是将原有的函数进行包装,即在不改变原有函数的前提下增强该函数的功能。

例如定义一个可以打印日志的装饰器,如下:

>>> def log(func):
...     def wrapper(*args, **kw):
...         print('call %s():' % func.__name__)
...         return func(*args, **kw)
...     return wrapper
...
>>> @log                  //把@log放到now()函数的定义处,相当于执行:now=log(now)
... def now():
...     print('2019-1-19')  
...
>>> now()                 //相当于执行now=log(now),log(now)将wrapper()返回给变量now
call now():
2019-1-19      
>>> now.__name__          //通过打印函数名可知now实际上调用的是wrapper()函数
'wrapper'

也可以定义一个带参数的装饰器,如下:

>>> def log(text):
...    def decorator(func):
...        def wrapper(*args, **kw):
...            print('%s %s():' % (text, func.__name__))
...            return func(*args, **kw)
...        return wrapper
...    retuen decorator
...
>>> @log('execute')        
... def now():
... print('2019-1-19')
...
>>> now()          //相当于执行now=log('execute')(now)
execute now():     //先执行log('execute')返回decorator()函数,            
2019-1-19          //再执行decorator(now)返回wrapper()函数,并将wrapper()函数赋值给now变量
>>> now.__name__
'wrapper'

五、偏函数

当我们要大量调用一个函数,而这个函数的参数个数比较多,我们又只需要改变其中一个函数时,可以通过调用functools模块的partial帮助我们创建一个偏函数来固定住不需要改变的参数(也就是设置默认值)。

int()函数的作用是将一个字符串转换成整数,它的默认参数base的值是10(即将字符串转换成十进制)。如果我们希望将字符串转换成二进制,则需要把base设置成2。当大量调用时,设置base会显得很繁琐,因此我们就可以通过创建偏函数来解决这个问题:

>>> int2 = functools.partial(int, base=2)
>>> int2('10010')
18

猜你喜欢

转载自blog.csdn.net/q1449516487/article/details/86528084
今日推荐