zoukankan      html  css  js  c++  java
  • Python高阶函数map、reduce、filter、sorted的应用

    what's the 高阶函数

      把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。

      python内置的高阶函数主要有map、reduce、filter、sorted,当然我们可以自己编写高阶函数

    Map函数 

      map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的对象返回,返回值是一个可迭代对象,可以用list()方法将其转为一个列表。 


    举例说明 
      比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下: 

    def f(x):
        return x * x
    
    # 用循环实现
    L = []
    for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
        L.append(f(n))
    print (L)# [1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    # 用map实现
    list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    # 用map将列表重的数字转换为字符串
    list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])) # ['1', '2', '3', '4', '5', '6', '7', '8', '9']

    Reduce函数 

      reduce把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

    #reduce函数不是内置函数,而是在模块functools中的函数,故需要导入
    from functools import 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, 3, 5, 7, 9]) # 25

      当然求和运算可以直接用Python内建函数sum(),没必要动用reduce。 但是如果要把序列 [1, 3, 5, 7, 9] 变换成整数13579,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的函数:

    def fn(x, y):
        return x * 10 + y
    
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    
    reduce(fn, map(char2num, '13579')) # 13579
    
    
    # 整理成一个str2int的函数就是:
    def str2int(s):
        def fn(x, y):
            return x * 10 + y
    
        def char2num(s):
            return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    
        return reduce(fn, map(char2num, s))

      上面的例子还可以用lambda函数进一步简化成:

    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    
    def str2int(s):
        return reduce(lambda x,y: x*10+y, map(char2num, s))

      也就是说,假设Python没有提供int()函数,完全可以自己写一个把字符串转化为整数的函数,而且只需要几行代码!

    Filter函数 

      Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。True保留,False丢弃 


      例如,在一个list中,删掉偶数,只保留奇数,可以这么写:

    def is_odd(n):
        return n % 2 == 1
    
    filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])# [1, 5, 9, 15]

      把一个序列中的空字符串删掉,可以这么写:

    def not_empty(s):
        return s and s.strip()
    
    filter(not_empty, ['A', '', 'B', None, 'C', '  ']) # ['A', 'B', 'C']

      所以用filter()关键在于正确实现一个“筛选”函数。

    sorted函数

      排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。  

      Python内置的sorted()函数就可以对list进行排序:

    sorted([36, 5, 12, 9, 21]) # [5, 9, 12, 21, 36]

      此外,sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,我们就可以自定义一个reversed_cmp函数:

    def reversed_cmp(x, y):
        if x > y:
            return -1
        if x < y:
            return 1
        return 0
    
    # 传入自定义的比较函数reversed_cmp,就可以实现倒序排序:
    sorted([36, 5, 12, 9, 21], reversed_cmp) # [36, 21, 12, 9, 5]

      再看一个字符串排序的例子:

    sorted(['bob', 'about', 'Zoo', 'Credit']) # ['Credit', 'Zoo', 'about', 'bob']

      默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。

      现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:

    def cmp_ignore_case(s1, s2):
        u1 = s1.upper()
        u2 = s2.upper()
        if u1 < u2:
            return -1
        if u1 > u2:
            return 1
        return 0
    
    
    sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case) # ['about', 'bob', 'Credit', 'Zoo']

               

    参考:https://www.cnblogs.com/fangbei/p/python-Map_Reduce_Filter.html 

    参考:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001418612033918f1f341b1e0f14762a118891fa52949aa000

       

  • 相关阅读:
    phpmyadmin设置密码,不用登录直接进入
    如何将本地文件复制到远程服务器听语音
    win7 64位wamp2.5无法启动MSVCR110.DLL丢失听语音
    最大连接数:60 iops:150 什么概念?
    北京可以备案什么域名
    远程桌面命令是什么 如何使用命令连接远程桌面
    如何知道电脑是几核?
    nohup命令与&区别,jobs,fg,bg,Ctrl-Z、Ctrl-C、Ctrl-D
    Shell 文件包含
    Shell 输入/输出重定向
  • 原文地址:https://www.cnblogs.com/zhuminghui/p/10558876.html
Copyright © 2011-2022 走看看