python 中的函数编程是离不开 map / reduce / filter / lambda 这几个家伙的。对于 list 实例使用它们,比单纯的用 for 循环遍历处理数据,要高效很多。但是要熟悉它们的语法,还是需要多一些重复练习。
lambda
lambda 可以快速的定义一个函数,比如创建一个可以将输入的数字做平方运算的函数:
f=lambda x:x**2
f(4)
16
这种语法表达,看上去跟 js 中的定义一个方法,并且将它赋予一个变量很相似。上面的代码如果用 js 来写,应该是:
f=function(x){return x**2}
console.log(f(4))
16
有了这种对比,就很容易记住 lambda 的语法表达了:冒号之前是input,冒号之后是output
用 map 来对 list 做遍历运算
语法: map(function,list_like_val)
计算 1-20 的立方,并且打印出来。
# 虽然这里可以直接写作 x**3 就得到答案了,但是为了表达 map 的使用方法,这一行只是为了创建一个list
# 许多使用环境里,可能都是通过查数据库获得某个 list,然后要做遍历操作
nums=[x for x in range(1,21)]
# map 的语法: map(list like val, function)
m=map(lambda x:'%d -- %d' % (x,x**3),nums)
','.join(m)
'1 -- 1,2 -- 8,3 -- 27,4 -- 64,5 -- 125,6 -- 216,7 -- 343,8 -- 512,9 -- 729,10 -- 1000,11 -- 1331,12 -- 1728,13 -- 2197,14 -- 2744,15 -- 3375,16 -- 4096,17 -- 4913,18 -- 5832,19 -- 6859,20 -- 8000'
用 fliter 来对 list 做过滤运算
语法: filter(function,list_like_val)
去掉数组中为空的元素
names=['Adam',None, 'Sarah','Terry',None,'Erwing']
new_names=filter(lambda x:x!=None,names)
# filter 运算不会改变原有数组的,下面的打印结果说明了一切
print names
print new_names
['Adam', None, 'Sarah', 'Terry', None, 'Erwing']
['Adam', 'Sarah', 'Terry', 'Erwing']
用 reduce 来对 list 做合并运算
语法: reduce(function,list_like_val)
从直观意义上,reduce 不是太好理解。reduce 字面意义是减少,但是看看下面这个案例:
n=[3,6,9]
reduce(lambda x,y:x+y,n)
18
其结果是将 3、6、9 加起来了。也就是说,在 lambda 中,x和y分别代表新的输入和上次计算的结果,有那么一点尾递归的意思。官方文档的解说是:reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). 这个表达式的对比,更容易从直观上理解 reduce 函数的意义。
reduce如果只是用来做相加运算,那么采用 sum() 函数也可以。但是如果是做相减、相乘、相除,sum()就干不了了。还有,如果做字符串运算呢?下面这个案例显示了用 reduce 来替代 join 方法。
reduce(lambda x,y:'%s,%s' % (x,y),n)
'3,6,9'
还可以将一个数组里的元素组合起来变成一个整数,比如有一个数组是[2,4,8,9],希望按顺序将其组合起来,变成 2489,使用 reduce也很方便,为了加深理解,特意写了几个数组来做对比,也反应了 reduce 合并的过程:
n=[2]
print reduce(lambda x,y:10*x+y,n)
n=[2,4]
print reduce(lambda x,y:10*x+y,n)
n=[2,4,8]
print reduce(lambda x,y:10*x+y,n)
n=[2,4,8,9]
print reduce(lambda x,y:10*x+y,n)
2
24
248
2489