pyhton 函数式编程

1.高阶函数

1.map/reduce

 

map()函数接收两个参数,一个是函数,一个是Iterablemap将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回

 

举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()。

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

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个IteratorIterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。(惰性序列即不运算出所有,运行一次计算一次)

map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数.

 

再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数reduce结果继续和序列的下一个元素做累积计算,其效果就是:

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

2.filter

 

Python内建的filter()函数用于过滤序列。

 

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

可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数

注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

3.sorted

 

排序算法

 

排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。

 

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]

key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。

 

要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True

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

从上述例子可以看出,高阶函数的抽象能力是非常强大的,而且,核心代码可以保持得非常简洁。

2.返回函数

 

函数作为返回值

 

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回,当把返回的函数调用时,才真正的计算出结果。

 

 请再注意一点,当我们调用这个函数时,每次调用都会返回一个新的函数,即使传入相同的参数,返回值函数的调用结果互不影响。

闭包

注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。(即闭包时返回函数的参数是一个引用,如果循环调用的话,返回后的函数参数值计算时使用的是最后的循环变量。)

3.匿名函数

 

关键字lambda表示匿名函数,冒号前面的x表示函数参数

 

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

 

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

 

posted @ 2018-06-01 22:22  QianweiZ  阅读(116)  评论(0)    收藏  举报