简单讲,”Map(映射)”和”Reduce(归约)”是一种编程模型,用于大规模数据集(大于1TB)的并行运算。Python内建了map()和reduce()函数。
map-映射
map函数接收两个参数,一个是函数,一个是可迭代对象Iterable,map把Iterable中的对象,依次作为参数给到函数,并返回结果生成新的Iterable。即map()函数可以实现如下效果:
f(x) = x * x
│
│
┌───┬───┬───┬───┼───┬───┬───┬───┐
│ │ │ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
[ 1 2 3 4 5 6 7 8 9 ]
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
[ 1 4 9 16 25 36 49 64 81 ]
实际操作一下:
>>> 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(x)=x2,还可以计算复杂函数,如将list数值转换为字符串:
>>> list(map(str,[1,2,3,4,5,6,7,8,9])) ['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce-规约
reduce就是把一个函数作用于一个序列,这个函数接收2个参数,reduce把序列中头两个数值接收运算后,再将结果与下一个数值传给函数计算结果,依次累积计算:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
例如对一个序列求和,用reduce实现:
>>> from functools import reduce >>> def add(x,y): return x + y >>> reduce(add,[1,2,3,4,5]) 15
当然了求和我们有sum函数,如果是把序列[1,2,3,4,5]变成整数12345呢?
>>> from functools import reduce >>> def fn(x,y): return x * 10 + y >>> reduce(fn,[1,2,3,4,5]) 12345
结合上面的例子,加上map(),可以编写出把str转换为int的函数:
>>> def fn(x,y): return x * 10 + y >>> def char2num(s): digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} return digits[s] >>> reduce(fn,map(char2num,'12345')) 12345
优化整理,得到一个str2int函数:
>>> from functools import reduce >>> digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} >>> def str2int(s): def fn(x,y): return x * 10 + y def char2num(s): return digits[s] return reduce(fn,map(char2num,s)) >>> str2int('12345') 12345