匿名函数和lambda:
lambda [args1,[args2]] : expression
python 使用lambda来创建匿名函数,匿名函数不需要以标准的方式进行创建,但是作为函数,它们也能有参数,一个完整的lambad语句代表了一个表达式,这个表达式的定义体和声明体必须在同一行。
1. 参数是可选的
lambda : True
在上面的例子中,没有使用参数创建了一个函数对象,但是在程序中没有在任何地方保存它也没有调用它,这个函数对象的引用计数在函数创建的时候被设置为True,但是因为没有引用被保存下来计数很快就会到0,然后被垃圾回收机制回收。针对于这种情况lambda最好使用在不需要多次调用的函数定义上
true = lambda: True
true() # 会输出True
2. 使用参数构建lambda
def add(x, y): return x + y lambda x,y: x+y
上面定义的两个函数计算效果是等价的。
3. 函数式编程的几个常用函数filter map reduce
1. filter(func, seq) 调用一个布尔函数,func用来迭代遍历每个seq中的元素,返回一个使func返回值为true的元素的序列
1 data = [1, 2, 3, 4, 5, 6, 7, 8] 2 3 def testFilter(): 4 result = filter(lambda x:x%2, data) 5 for eachitem in result: 6 print(eachitem) 7 8 if __name__ == "__main__": 9 testFilter()
上面的例子查找返回集合中奇数的列表,
针对与filter函数的效果其实有一种更好的方式,列表表达式
1 data = [1, 2, 3, 4, 5, 6, 7, 8] 2 3 def testFilter(): 4 print([item for item in data if item % 2])
2. map内建函数和filter相似,都是通过函数来处理序列,但是不像filter,map将函数调用映射到序列的每个元素上,并返回一个函数所有返回值的列表。
1 data = [1, 2, 3, 4, 5, 6, 7, 8] 2 3 def testmap(): 4 result = map(lambda x: x**2, data) 5 for item in result: 6 print(item) 7 8 def testmap2(): 9 result = map(lambda x,y:x+y,data[:3],data[4:]) 10 for item in result: 11 print(item) 12 13 if __name__ == "__main__": 14 testmap() 15 testmap2()
上面的代码要注意一点:如果map函数中传入的func有一个参数,那么在map传入的一个序列,如果map函数中传入的func有多个参数,那么传入的序列个数为相应的个数,并且在同时将每一个序列中相应的位置的元素一同传入到func中。将所有的返回值组成列表。
3. reduce 使用一个二元函数(接收两个值作为输入,一个输出),一个序列和一个可选的初始化器。
函数通过取出序列的头俩个值传入func中计算,将计算结果返回,和序列的下一个元素一起作为参数传递到func中,直到遍历所有的元素之后返回一个单一的值。
reduce(func,(1,2,3)) == func(func(1,2),3)
1 from functools import reduce 2 data = [1, 2, 3, 4, 5, 6, 7, 8] 3 4 def testreduce(): 5 result = reduce(lambda x,y: x + y, data) 6 print(result) 7 8 if __name__ == "__main__": 9 testreduce()
注意在python3之后reduce不再是内建函数而是改在functools中了。