以下内容主要针过滤函数filter , 映射和归并函数map/reduce , 装饰器@ 以及 匿名函数lamda,具体内容如下:
1. 过滤函数filter
定义:filter 函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个列表中的元素;返回一个使bool_func返回值为true的元素的序列。
a=[0,1,2,3,4,5,6,7]
b=filter(None, a)
print b
</div>
输出结果:[1, 2, 3, 4, 5, 6, 7]
回到顶部
2. 映射和归并函数map/reduce
这里说的map和reduce是Python的内置函数,不是Goggle的MapReduce架构。
2.1 map函数
map函数的格式:map( func, seq1[, seq2...] )
Python函数式编程中的map()函数是将func作用于列表中的每一个元素,并用一个列表给出返回值。如果func为None,作用等同于一个zip()函数。
下图是当列表只有一个的时候,map函数的工作原理图:

举个简单的例子:将列表中的元素全部转换为None。
map(lambda x : None,[1,2,3,4])
</div>
输出:[None,None,None,None]。
当列表有多个时,map()函数的工作原理图:

也就是说每个seq的同一位置的元素在执行过一个多元的func函数之后,得到一个返回值,这些返回值放在一个结果列表中。
下面的例子是求两个列表对应元素的积,可以想象,这是一种可能会经常出现的状况,而如果不是用map的话,就要使用一个for循环,依次对每个位置执行该函数。
print map( lambda x, y: x * y, [1, 2, 3], [4, 5, 6] ) # [4, 10, 18]
</div>
上面是返回值是一个值的情况,实际上也可以是一个元组。下面的代码不止实现了乘法,也实现了加法,并把积与和放在一个元组中。
print map( lambda x, y: ( x * y, x + y), [1, 2, 3], [4, 5, 6] ) # [(4, 5), (10, 7), (18, 9)]
</div>
还有就是上面说的func是None的情况,它的目的是将多个列表相同位置的元素归并到一个元组,在现在已经有了专用的函数zip()了。
print map( None, [1, 2, 3], [4, 5, 6] ) # [(1, 4), (2, 5), (3, 6)]
print zip( [1, 2, 3], [4, 5, 6] ) # [(1, 4), (2, 5), (3, 6)]
</div>
注意:不同长度的多个seq是无法执行map函数的,会出现类型错误。
2.2 reduce函数
reduce函数格式:reduce(func, seq[, init]).
reduce函数即为化简,它是这样一个过程:每次迭代,将上一次的迭代结果(第一次时为init的元素,如没有init则为seq的第一个元素)与下一个元素一同执行一个二元的func函数。在reduce函数中,init是可选的,如果使用,则作为第一次迭代的第一个元素使用。
简单来说,可以用这样一个形象化的式子来说明:
reduce(func, [1,2,3])=func(func(1,2), 3)
</div>
reduce函数的工作原理图如下所示:

举个例子来说,阶乘是一个常见的数学方法,Python中并没有给出一个阶乘的内建函数,我们可以使用reduce实现一个阶乘的代码。
n = 5
print reduce(lambda x, y: x * y, range(1, n + 1)) # 120
</div>
那么,如果我们希望得到2倍阶乘的值呢?这就可以用到init这个可选参数了。
m = 2
n = 5
print reduce( lambda x, y: x * y, range( 1, n + 1 ), m ) # 240
</div>
回到顶部
3. 装饰器@
3.1 什么是装饰器(函数)?
定义:装饰器就是一函数,用来包装函数的函数,用来修饰原函数,将其重新赋值给原来的标识符,并永久的丧失原函数的引用。
3.2 装饰器的用法
先举一个简单的装饰器的例子:
#-*- coding: UTF-8 -*-
import time
def foo():
print 'in foo()'
</div>
# 定义一个计时器,传入一个,并返回另一个附加了计时功能的方法
def timeit(func):
</div>
# 定义一个内嵌的包装函数,给传入的函数加上计时功能的包装
def wrapper():
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
</div>
# 将包装后的函数返回
return wrapper
foo = timeit(foo)
foo()
</div>
输出:
in foo()
used: 2.38917518359e-05
</div>
python中专门为装饰器提供了一个@符号的语法糖,用来简化上面的代码,他们的作用一样。上述的代码还可以写成这样(装饰器专有的写法,注意符号“@”):

