• python函数式编程之高阶函数学习



    基本概念

    函数式编程,是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量。因此,任意一个函数,只要输入确定,输出就确定的这种函数我们称之为纯函数,我们称这种函数没有副作用。而允许使用白变量的程序设计语言,由于函数内部的变量状态是不确定的,同样的输入可能有不同的输出,我们称这种函数为有副作用的。
    函数式编程的一个特点就是,允许把函数本身作为参数传递给另一个函数,还允许返回一个函数!
    Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
    (这部分内容摘抄与廖雪峰老师的博客文章,自己也进行了学习)

    高阶函数

    • 变量可以指向函数

        #变量可以指向函数
        f = abs;
        print(abs(-10));#10
        print(f(-10));#10
        #在这里用f和abs调用的结果和效果是一样的
      

    说明变量f 已经指向了函数 abs本身。

    • 函数名也是变量
      函数名就是指向函数的变量。如:

        abs = 10;
        print(abs(-10));
        # Traceback (most recent call last):
        #   File "test01.py", line 164, in <module>
        #     print(abs(-10));
        # TypeError: 'int' object is not callable
      

    abs已经被赋值10,是一个指向10的变量了,就不能通过abs(-10)来调用该函数了,因为abs这个变量已经不指向求绝对值函数了。

    • 传入函数
      就是一个函数可以作为另一个函数的参数,这种函数称为高阶函数。

        #一个简单的高阶函数
        def add(x, y, f):
        	return f(x) + f(y);
        print(add(5, -6, abs));#11
      
    map/reduce

    python内建了map()和reduce()函数。

    • map()函数
      map函数接收两个参数,一个是函数,一个是iterable(可迭代的对象),map将传入的函数一次作用到序列的每个元素,并把结果作为新的iterator返回。

        #map()函数
        def f(x):
        	return x * x;
        r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
        print(list(r));
        # [1, 4, 9, 16, 25, 36, 49, 64, 81]
      
    • reduce()函数
      该函数必须接收两个参数,reduce把函数结果继续和序列的下一个元素做累积计算。
      如:累加

        #reduce()函数
        from functools import reduce;
        def add1(x, y):
        	return x + y;
        print(reduce(add1, [1, 3, 5, 7, 9]));#25
      

    这并不是reduce的用武之地,当我们要把上面的数列变成整数13579时,reduce就排上用场了:

    	def fn(x, y):
    		return x * 10 + y;
    	print(reduce(fn, [1, 3, 5, 7, 9]));
    

    这个例子也没什么意义,但是当我们要把字符串 str 转换成int的函数时,就用上了reduce(结合map)。

    filter()函数
    • filter
      python内置的filter函数用于过滤序列。和map类似也接收一个函数和一个序列,但是不同的是,filter把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
      在一个list中,删掉偶数,只保留奇数:

        #filter函数
        #在一个list中删除偶数,只保留奇数
        def is_odd(n):
        	return n % 2 == 1;
        print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])));
        # 1, 5, 9, 15
      
    • 用filter求素数
      思想:计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:

    1. 首先,列出从2开始的所有自然数,构造一个序列:

       2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
      
    2. 取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:

       3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
      
    3. 取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:

       5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
      
    4. 取新序列的第一个数5,然后用5把序列的5的倍数筛掉:

       7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
      

    不断筛下去,就可以得到所有的素数。
    注明:该算法描述来源于廖雪峰老师的文章。

    sorted()函数

    排序算法

    #sorted函数排序
    print(sorted([36, -2, 5, 7, 1, -10]));
    # [-10, -2, 1, 5, 7, 36];
    

    sorted也是一个高阶函数,可以接受一个key函数来实现自定义的排序,列如按绝对值大小排序:

    #sorted函数排序
    print(sorted([36, -2, 5, 7, 1, -10], key=abs));
    # [1, -2, 5, 7, -10, 36]
    

    sorted函数可以用来对字符串进行排序。
    sorted()也是一个高阶函数。用sorted()排序的关键在于实现一个映射函数。

    总结

    对函数式编程的学习这部分比较重要,学习这部分让我想到了前端框架reactJs,react也是强调函数式编程的,也是react的特性。就是说一个函数可可以作为另一个函数的参数。上面的学习例子都是很简单的,需要自己不断的练习。

  • 相关阅读:
    js 前端词典对象的属性和值读取
    Vue 标签Style 动态三元判断绑定
    Java搭建MapReduce输出到DB具体步骤之多输入
    Java搭建MapReduce输出到DB具体步骤
    Java搭建MapReduce完成二次排序步骤
    新生迎新
    Java搭建MapReduce具体步骤
    Java访问HDFS集群Java语句以及 Linux操作HDFS集群常用命令
    Linux操作HDFS常用命令
    Linux操作HDFS集群常用命令
  • 原文地址:https://www.cnblogs.com/yehui-mmd/p/7875497.html
Copyright © 2020-2023  润新知