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 利用mapreduce编写一个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)

  

posted @   minseo  阅读(373)  评论(0编辑  收藏  举报
编辑推荐:
· 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)
点击右上角即可分享
微信分享提示