zoukankan      html  css  js  c++  java
  • Python之高阶函数map/reduce

      Python内建map()和reduce()函数

      map()函数接收两个参数一个是函数一个是一个Iterable(迭代器),并把结果作为新的Iterator(生成器)返回

      有一个函数f(x)=x*x作用于序列list[1,2,3,4,5,6,7,8,9]

      使用python函数实现

    >>> 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函数而使用一个循环实现如下

    >>> 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所有数字转为字符串:

    >>> list(map(str,[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把结果继续和序列的下一个元素做累积计算,其效果就是:

    reduce(f,[x1,x2,x3.x4])=f(f(f(x1,x2),x3),x4)
    

      比如一个序列求和

    >>> from functools import reduce
    >>> def add(x,y):
    ...   return x+y
    ... 
    >>> reduce(add,[1,3,5,7,9])
    25
    

      

    #执行顺序如下
    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实现

    >>> sum([1,3,5,7,9])
    25
    

      但是如果需要把序列[1,3,5,7,9]变成整数就可以使用reduce

    >>> 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

    >>> int('13579')
    13579
    

      假设python不带int函数怎么把str '13579'转换成整数13579

      思路

       char2num.py

    #加载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))
    

      运行输出如下

    需要转换成整数的字符串是 13579
    使用map转换后的生成器 <map object at 0x7f5cbec4e7b8>
    13579
    

      改成函数char2num_fuction.py 

    #加载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

    def normalize(name):
        return name.title()
    
    L1=['adam','LISA','barT']
    L2=list(map(normalize,L1))
    print(L2)
    

      输出

    ['Adam', 'Lisa', 'Bart']
    

      

      练习2 请编写一个prod()函数,可以接受一个list并利用reduce()求积:

      prod.py

    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

    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)
    

      

  • 相关阅读:
    设计模式之原型模式
    Mac OSx下的APK反编译
    Android中ListView封装收缩与展开
    带密码登录的密码保险箱应用源码
    HTML 5缓存机制:Cache Manifest配置实例
    PHP开发大型项目的一点经验
    Windows Phone 编程: 摇一摇 效果
    swift皮筋弹动发射飞机
    Win8.1应用开发之适配器模式(C#实现)
    java实现身份证校验
  • 原文地址:https://www.cnblogs.com/minseo/p/11046737.html
Copyright © 2011-2022 走看看