今天我们来看看Python 中Map/Reduce 这两个经典的函数式编程工具,从基础用法到实战案例。Map、Reduce是Google提出的处理大数据的思想。首先map()函数会将一个函数作用于可迭代对象的每一个元素,返回一个迭代器对象,简单的说就是批量处理列表里的所有元素,不用写for循环# lambda 匿名函数 + map 批量计算:每个数字自加a = map(lambda x: x+x, [1,2,3,4,5])# 迭代器转列表查看结果print(list(a))# 输出结果:[2, 4, 6, 8, 10]
而reduce()函数,对于可迭代对象中的元素依次进行累计计算,最终返回一个结果值。计算原理reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
在了解了基本的用法,我们通过一个实例来实现字符串转浮点数,不使用内置的float():# Python3 必须导入 reduce!from functools import reduce# 字符映射表:字符 → 数字,. 标记为 -1DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '.': -1}# 单个字符转数字def char2num(s): return DIGITS[s]# 核心累积计算函数def func(x, y): # 第一次计算:x 是数字 if type(x) == int: if x == -1: return (0 + y, 0.1) elif y == -1: return (x, 0.1) else: return (x*10+y, 1) # 后续计算:x 是元组(整数部分+小数位权重) elif type(x) == tuple: if y == -1: return (x[0], 0.1) else: if x[1] < 1: res = x[1] * 0.1 return (x[0] + y * x[1], res) else: res = 1 return (x[0]*10 + y, res)# 字符串转浮点数主函数def str2float(s): # map:逐个字符转数字 L = map(char2num, s) # reduce:累积计算出最终浮点数 r = reduce(func, L) return r[0]# 测试代码if __name__ == "__main__": # 测试1:普通小数 if abs(str2float('123.4') - 123.4) < 0.00001: print('测试1:成功!') else: print('测试1:失败!') # 测试2:纯整数 if abs(str2float('123456') - 123456) < 0.00001: print('测试2:成功!') else: print('测试2:失败!') # 测试3:带前导零的小数 if abs(str2float('0.123456') - 0.123456) < 0.00001: print('测试3:成功!') else: print('测试3:失败!')
上面的代码中char2num借助映射表,把字符串里的每个字符转换成对应的数字;map(char2num,s)批量转换整个字符串,得到数字序列;reduce(func,L)积累计算,区分整数部分和小数部分,最终拼接成完整浮点数;而测试用例中,覆盖了纯小数、普通小数、带前导零的小数三种场景。今天就到这里了,有兴趣可以自己跑一跑测试程序,深入理解一下。