Python从放弃到入门——函数式编程Functional Programming

Python支持多种编程范式:过程式(使用基础的语句),面向对象式(使用类)和函数式
对于函数式编程,Python提供了一整套进行函数式编程的内置工具,如map,filter,reduce。
此外,还支持嵌套作用域闭包、匿名函数lambda、生成器,函数装饰器和类装饰器。

在Python中,一切皆为对象。
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。

a=abs
print(a(-9))
9

map

程序对列表和其他序列常常要做的一件事,就是对每个元素进行一个操作并把其结果收集起来。
如下面的例子所示,可以使用for循环来更新一个列表中所有的数字。

counters=[1,2,3,4]
updated=[]
for x in counters:
    updated.append(x+10)
print(updated)
[11, 12, 13, 14]

除此之外,我们还可以用map函数来实现。

def inc(x):
    return x+10
print(list(map(inc,counters)))
[11, 12, 13, 14]

map()函数接收两个参数,一个是函数,一个是Iterable。
map函数将被传入的函数作用到每个可迭代对象的每一个元素上,并把结果作为新的Iterator返回。
由于map返回的是一个可迭代对象Iterator(详见迭代器章节),Iterator是惰性序列,因此要用list调用来强制他产生所有的结果以显示。

更进一步,如果我们将函数改成lambda表达式,同样功能的代码将缩减到一行。正是由于这些高度抽象的工具存在,python才可以写出非常简洁的代码。

print(list(map(lambda x:x+10,counters)))
[11, 12, 13, 14]

我们来看一下map源码的定义。在类map定义的函数中,通过__init__函数我们可以看到map的参数类型。
以及实现了__iter__和__next__方法从而作为一个迭代器。

class map(object):
    """
    map(func, *iterables) --> map object
    
    Make an iterator that computes the function using arguments from
    each of the iterables.  Stops when the shortest iterable is exhausted.
    """
    def __getattribute__(self, *args, **kwargs): # real signature unknown
        """ Return getattr(self, name). """
        pass

    def __init__(self, func, *iterables): # real signature unknown; restored from __doc__
        pass

    def __iter__(self, *args, **kwargs): # real signature unknown
        """ Implement iter(self). """
        pass

    @staticmethod # known case of __new__
    def __new__(*args, **kwargs): # real signature unknown
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass

    def __next__(self, *args, **kwargs): # real signature unknown
        """ Implement next(self). """
        pass

    def __reduce__(self, *args, **kwargs): # real signature unknown
        """ Return state information for pickling. """
        pass

filter

和map()一样,filter()也接收一个函数和一个序列。
filter函数将被传入的函数作用到每个可迭代对象的每一个元素上,如果函数对该元素返回了True值,这个元素就会被加入结果列表中。
和map一样,filter()函数返回的也是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

def positive(x):
    if x>0:
        return x
print(list(filter(positive,range(-5,5))))
[1, 2, 3, 4]

前面说到filter的功能非常类似生成式带if的语法,让我们来回顾一下,

print([i for i in range(-5,5) if i>0])
[1, 2, 3, 4]

同样,我们也可以把函数定义成lambda表达式

print(list(filter(lambda x:x>0,range(-5,5))))
[1, 2, 3, 4]

python中实现一种功能的方式多样,学会如何取舍,灵活使用往往能达到事半功倍的效果。

reduce

reduce函数接收一个函数和一个序列。这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,使用前需先导入。

import functools
def add(x,y):
    return x+y
print(functools.reduce(add,[1,2,3,4]))
10

reduce的定义与map/filter相比则简单许多。函数文档中有示例来解析reduce的作用。

def reduce(function, sequence, initial=None): # real signature unknown; restored from __doc__
    """
    reduce(function, sequence[, initial]) -> value
    
    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.
    """
    pass

本节介绍了函数式编程的内置工具,map,filter,reduce,即函数作为另一个函数的参数。下一节将介绍函数作为返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值