Python之高阶函数map/reduce
Python内建map()和reduce()函数
map()函数接收两个参数一个是函数一个是一个Iterable(迭代器),并把结果作为新的Iterator(生成器)返回
有一个函数f(x)=x*x作用于序列list[1,2,3,4,5,6,7,8,9]
使用python函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> r = map (f, range ( 1 , 4 )) >>> r < map object at 0x7fcec039ee80 > >>> list (r) [ 1 , 4 , 9 ] >>> def f(x): ... return x * x ... >>> r = map (f,[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]) >>> r < map object at 0x7fcec039eda0 > >>> list (r) [ 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 ] |
map传递的第一个参数是f是一个函数本身,第二个参数为一个迭代器,结果为生成器Iterator所以需要使用list函数打印才能打印
也可以不使用map函数而使用一个循环实现如下
1 2 3 4 5 6 | >>> L = [] >>> for i in range ( 1 , 11 ): ... L.append(i * i) ... >>> print (L) [ 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 , 100 ] |
map()
作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:
1 2 | >>> list ( map ( str ,[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])) [ '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ] |
同理以上可以使用循环实现
1 2 3 4 5 6 7 8 9 | >>> L = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] >>> L [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] >>> L1 = [] >>> for i in L: ... L1.append( str (i)) ... >>> print (L1) [ '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ] |
使用map可以一行代码实现
reduce的用法
reduce
把一个函数作用在一个序列[x1, x2, x3, ...]
上,这个函数必须接收两个参数,reduce
把结果继续和序列的下一个元素做累积计算,其效果就是:
1 | reduce (f,[x1,x2,x3.x4]) = f(f(f(x1,x2),x3),x4) |
比如一个序列求和
1 2 3 4 5 6 | >>> from functools import reduce >>> def add(x,y): ... return x + y ... >>> reduce (add,[ 1 , 3 , 5 , 7 , 9 ]) 25 |
1 2 3 4 5 6 | #执行顺序如下 add(add(add(add( 1 , 3 ), 5 ), 7 ), 9 ) add(add(add( 4 , 5 ), 7 ), 9 ) add(add( 9 , 7 ), 9 ) add( 16 , 9 ) 25 |
求和运算可以使用python内建函数sum实现
1 2 | >>> sum ([ 1 , 3 , 5 , 7 , 9 ]) 25 |
但是如果需要把序列[1,3,5,7,9]变成整数就可以使用reduce
1 2 3 4 5 6 | >>> from functools import reduce >>> def fn(x,y): ... return x * 10 + y ... >>> reduce (fn,[ 1 , 3 , 5 , 7 , 9 ]) 13579 |
这个例子本身没多大用处,但是,如果考虑到字符串str
也是一个序列,对上面的例子稍加改动,配合map()
,我们就可以写出把str
转换为int
的函数:
PS:python内置函数int可以把str转换成int
1 2 | >>> int ( '13579' ) 13579 |
假设python不带int函数怎么把str '13579'转换成整数13579
思路
char2num.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #加载reduce模块 from functools import reduce def fn(x,y): return x * 10 + y #定义函数把字符串转换成数字参数为字符串‘1’,返回为整数1 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] s = '13579' print ( '需要转换成整数的字符串是' ,s) #使用map函数生成迭代器,迭代后输出为[1,3,5,7,9] l = map (char2num,s) print ( '使用map转换后的生成器' ,l) #使用reduce把生成的序列计算成整数 #计算过程为 #reduce(fn,[1,3,5,7,9]) #fn(fn(fn(fn(1,3),5),7),9) #fn(fn(fn(13,5),7),9) #fn(fn(135,7),9) #fn(1357,9) #13579 print ( reduce (fn,l)) |
运行输出如下
1 2 3 | 需要转换成整数的字符串是 13579 使用 map 转换后的生成器 < map object at 0x7f5cbec4e7b8 > 13579 |
改成函数char2num_fuction.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #加载reduce模块 from functools import reduce def char2int(s): def fn(x,y): return x * 10 + y #定义函数把字符串转换成数字参数为字符串‘1’,返回为整数1 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] return ( reduce (fn, map (char2num,s))) s = '13579' print (char2int(s)) |
练习1 利用map函数把用户不规范输入的字符串改成规范及首字母大写其余小写
normalize.py
1 2 3 4 5 6 | def normalize(name): return name.title() L1 = [ 'adam' , 'LISA' , 'barT' ] L2 = list ( map (normalize,L1)) print (L2) |
输出
1 | [ 'Adam' , 'Lisa' , 'Bart' ] |
练习2 请编写一个prod()
函数,可以接受一个list并利用reduce()
求积:
prod.py
1 2 3 4 5 6 7 8 9 | from functools import reduce def fn(x,y): return x * y def prod(L): return reduce (fn,L) PROD = prod([ 3 , 5 , 7 , 9 ]) print (PROD) |
练习3 利用map
和reduce
编写一个str2float
函数,把字符串'123.456'
转换成浮点数123.456
:
str2float.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | from functools import reduce def str2float(s): 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] s1,s2 = s.split( '.' ) #字符串'123.456'使用.号分割后的列表为['123','456']分别赋值给s1 s2 s1 = reduce (fn, list ( map (char2num,s1))) #由字符串'123'转换成整数123 s2 = reduce (fn, list ( map (char2num,s2))) #由字符串'456'转换成整数456 while s2> = 1 : #如果s2>=1 s2 = s2 / 10 #则除以10取商一直到s2<1 最后s2=0.456浮点数 return s1 + s2 #整数加小数作为函数结果返回 s = str2float( '123.456' ) print (s) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2018-06-18 ELk之使用kibana展示访问IP地图
2018-06-18 ELK之生产日志收集构架(filebeat-logstash-redis-logstash-elasticsearch-kibana)