• 内置函数——Filter & Map & Reduce


    filter

    filter(...)
        filter(function or None, sequence) -> list, tuple, or string

    说明:

          对sequence中的item依次执行function(item),将执行结果为True(!=0)的item组成一个List/String/Tuple(取决于sequence的类型)返回,False则退出(0),进行过滤。

    例子

    >>> def div(n):return n%2
    ... 
    >>> filter(div,range(5))                    #返回div输出的不等于0的真值
    [1, 3]
    >>> filter(div,range(10))
    [1, 3, 5, 7, 9]
    >>> filter(lambda x : x%2,range(10))        #lambda 函数返回奇数,返回列表
    [1, 3, 5, 7, 9]
    >>> filter(lambda x : not x%2,range(10))
    [0, 2, 4, 6, 8]
    >>> def fin(n):return n!='z'                #过滤'z' 函数,出现z则返回False
    ... 
    >>> filter(fin,'zhoujy')                    #'z'被过滤
    'houjy'
    >>> filter(lambda x : x !='z','zhoujy')     #labmda返回True值
    'houjy'
    >>> filter(lambda x : not x=='z','zhoujy')  #返回:字符串
    'houjy'

    filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。

    例如,要从一个list [1, 4, 6, 7, 9, 12, 17]中删除偶数,保留奇数,首先,要编写一个判断奇数的函数:

    def is_odd(x):
        return x % 2 == 1

    然后,利用filter()过滤掉偶数:

    >>>filter(is_odd, [1, 4, 6, 7, 9, 12, 17])

    结果:

    [1, 7, 9, 17]

    利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:

    def is_not_empty(s):
        return s and len(s.strip()) > 0
    >>>filter(is_not_empty, ['test', None, '', 'str', '  ', 'END'])

    结果:

    ['test', 'str', 'END']

    注意: s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。

    当rm为空时,默认删除空白符(包括' ', ' ', ' ', ' '),如下:

    >>> a = ' 123'
    >>> a.strip()
    '123'

    >>> a = ' 123 '
    >>> a.strip()
    '123'

    练习:

    请利用filter()过滤出1~100中平方根是整数的数,即结果应该是:

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    方法:

    import math
    def is_sqr(x):
        return math.sqrt(x) % 1 == 0
    print filter(is_sqr, range(1, 101))

    结果:

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

     

    filter
    filter为“过滤”、“筛选”之意。指数组filter后,返回过滤后的新数组。用法跟map极为相似:
    array.filter(callback,[ thisObject]);
    filter的callback函数需要返回布尔值true或false. 如果为true则表示,恭喜你,通过啦!如果为false, 只能高歌“我只能无情地将你抛弃……”。
    可能会疑问,一定要是Boolean值吗?我们可以简单测试下嘛,如下:
    var data = [0, 1, 2, 3];
    var arrayFilter = data.filter(function(item) {
        return item;
    });
    console.log(arrayFilter); // [1, 2, 3]
    有此可见,返回值只要是弱等于== true/false就可以了,而非非得返回 === true/false.
    因此,我们在为低版本浏览器扩展时候,无需关心是否返回值是否是纯粹布尔值(见下黑色代码部分):
    if (typeof Array.prototype.filter != "function") {
      Array.prototype.filter = function (fn, context) {
        var arr = [];
        if (typeof fn === "function") {
           for (var k = 0, length = this.length; k < length; k++) {
              fn.call(context, this[k], k, this) && arr.push(this[k]);
           }
        }
        return arr;
      };
    }
    接着上面map筛选邮件的例子,您可以狠狠地点击这里:兼容处理后filter方法测试demo
    主要测试代码为:
    var emailsZhang = users
      // 获得邮件
      .map(function (user) { return user.email; })
      // 筛选出zhang开头的邮件
      .filter(function(email) {  return /^zhang/.test(email); });
    
    console.log(emailsZhang.join(", ")); // zhang@email.com
    filter demo页面的结果截图 张鑫旭-鑫空间-鑫生活
    实际上,存在一些语法糖可以实现map+filter的效果,被称之为“数组简约式(Array comprehensions)”。目前,仅FireFox浏览器可以实现,展示下又不会怀孕:
    var zhangEmails = [user.email for each (user in users) if (/^zhang/.test(user.email)) ];
    
    console.log(zhangEmails); // [zhang@email.com]
    JS中使用filter

    map

    map(...)
        map(function, sequence[, sequence, ...]) -> list

    Python中的map函数应用于每一个可迭代的项,返回的是一个结果list。如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理。map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

    有一个list, L = [1,2,3,4,5,6,7,8],我们要将f(x)=x^2作用于这个list上,那么我们可以使用map函数处理。

    >>> L = [1,2,3,4,] 
    >>> def pow2(x): 
    ... return x*x 
    ... 
    >>> map(pow2,L) 
    [1, 4, 9, 16] 

    说明:

          对sequence中的item依次执行function(item),执行结果输出为list。

    例子:

    >>> map(str, range(5))           #对range(5)各项进行str操作
    ['0', '1', '2', '3', '4']        #返回列表
    >>> def add(n):return n+n
    ... 
    >>> map(add, range(5))           #对range(5)各项进行add操作
    [0, 2, 4, 6, 8]
    >>> map(lambda x:x+x,range(5))   #lambda 函数,各项+本身
    [0, 2, 4, 6, 8]
    >>> map(lambda x:x+1,range(10))  #lambda 函数,各项+1
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> map(add,'zhoujy')            
    ['zz', 'hh', 'oo', 'uu', 'jj', 'yy']
    
    #想要输入多个序列,需要支持多个参数的函数,注意的是各序列的长度必须一样,否则报错:
    >>> def add(x,y):return x+y
    ... 
    >>> map(add,'zhoujy','Python')
    ['zP', 'hy', 'ot', 'uh', 'jo', 'yn']
    >>> def add(x,y,z):return x+y+z
    ... 
    >>> map(add,'zhoujy','Python','test')     #'test'的长度比其他2个小
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: add() takes exactly 2 arguments (3 given)
    
    >>> map(add,'zhoujy','Python','testop')
    ['zPt', 'hye', 'ots', 'uht', 'joo', 'ynp']

    JS中使用map方法

    map方法的作用不难理解,“映射”嘛,也就是原数组被“映射”成对应新数组。下面这个例子是数值项求平方:
    var data = [1, 2, 3, 4];
    
    var arrayOfSquares = data.map(function (item) {
      return item * item;
    });
    
    alert(arrayOfSquares); // 1, 4, 9, 16
    callback需要有return值,如果没有,就像下面这样:
    var data = [1, 2, 3, 4];
    var arrayOfSquares = data.map(function() {});
    
    arrayOfSquares.forEach(console.log);
    结果如下图,可以看到,数组所有项都被映射成了undefined:

    上面的操作如下图

    在实际使用的时候,我们可以利用map方法方便获得对象数组中的特定属性值们。例如下面这个例子(之后的兼容demo也是该例子):
    var users = [
      {name: "张含韵", "email": "zhang@email.com"},
      {name: "江一燕",   "email": "jiang@email.com"},
      {name: "李小璐",  "email": "li@email.com"}
    ];
    
    var emails = users.map(function (user) { return user.email; });
    
    console.log(emails.join(", ")); // zhang@email.com, jiang@email.com, li@email.com

    Reduce

    reduce(...)
        reduce(function, sequence[, initial]) -> value

    说明:

          对sequence中的item顺序迭代调用function,函数必须要有2个参数。要是有第3个参数,则表示初始值,可以继续调用初始值,返回一个值。

    例子:

    >>> def add(x,y):return x+y
    ... 
    >>> reduce(add,range(10))        #1+2+3+...+9
    45
    >>> reduce(add,range(11))        #1+2+3+...+10
    55
    >>> reduce(lambda x,y:x*y,range(1,3),5)           #lambda 函数,5是初始值, 1*2*5
    10
    >>> reduce(lambda x,y:x*y,range(1,6))             #阶乘,1*2*3*4*5
    120
    >>> reduce(lambda x,y:x*y,range(1,6),3)           #初始值3,结果再*3
    360
    >>> reduce(lambda x,y:x+y,[1,2,3,4,5,6])          #1+2+3+4+5+6
    21 

    应用map,reduce,filter

    1):实现5!+4!+3!+2!+1!

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    def add_factorial(n):
        empty_list=[]           #声明一个空列表,存各个阶乘的结果,方便这些结果相加
        for i in map(lambda x:x+1,range(n)):    #用传进来的变量(n)来生成一个列表,用map让列表都+1,eg:range(5) => [1,2,3,4,5]
            a=reduce(lambda x,y:x*y,map(lambda x:x+1,range(i)))   #生成阶乘,用map去掉列表中的0
            empty_list.append(a)            #把阶乘结果append到空的列表中
        return empty_list
    if __name__ == '__main__':
        import sys
    #2选1
    #(一)
        try:
            n = input("Enter a Number(int) : ")
            result=add_factorial(n)   #传入变量
            print reduce(lambda x,y:x+y,result)      #阶乘结果相加
        except (NameError,TypeError):
            print "That's not a Number!"
    #(二)
    #    result = add_factorial(int(sys.argv[1]))   #传入变量
    #    print reduce(lambda x,y:x+y,result)      #阶乘结果相加

    结果:

    zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py
    Enter a Number(int) : 1
    1
    zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py
    Enter a Number(int) : 2
    3
    zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py
    Enter a Number(int) : 3
    9
    zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py
    Enter a Number(int) : 4
    33
    zhoujy@zhoujy:~/桌面/Python/4$ python factorial.py
    Enter a Number(int) : 5
    153
    zhoujy@zhoujy:~/桌面/Python/4$ 

    2):将100~200以内的质数挑选出来

    思路:

    质数是指:只有1和它本身两个因数,如2、3、5、7都是质数,即能被1和本身整除,1不是质数。
    比如一个数字N,看它是否质数的话,就要看:有没有能整除【2,N】之间的数X(不包含本身),即N%X是否为0,要是没有就为质数。
    所以我们要实现的算法是:拿一个数字N,去除以【2,N】之间的数X,来得到质数,即:N/2,N/3,……,N/N-2,N/N-1   ===> N/range(2,N)

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    def is_prime(start,stop):
        stop  = stop+1     #包含列表右边的值
        prime = filter(lambda x : not [x%i for i in range(2,x) if x%i == 0],range(start,stop))   #取出质数,x从range(start,stop) 取的数
        print prime
    
    if __name__ == '__main__':
        try :
            start = input("Enter a start Number :")
        except :
            start = 2   #开始值默认2
        try :
            stop  = input("Enter a stop  Number :")
        except :
            stop  = 0   #停止数,默认0,即不返回任何值
        is_prime(start,stop)

    结果:

    zhoujy@zhoujy:~/桌面/Python/4$ python prime.py 
    Enter a start Number :
    Enter a stop  Number :10
    [2, 3, 5, 7]
    zhoujy@zhoujy:~/桌面/Python/4$ python prime.py 
    Enter a start Number :10
    Enter a stop  Number :20
    [11, 13, 17, 19]
    zhoujy@zhoujy:~/桌面/Python/4$ python prime.py 
    Enter a start Number :
    Enter a stop  Number :
    []
  • 相关阅读:
    vue 中的虚拟dom
    Vue基操
    表头固定,表的主体设置滚动条,同时解决错位问题
    AngularJS处理服务器端返回的JSON数据的格式问题
    jQuery ajax-param()
    Bootstrap中内联单选按钮
    angularJS中控制器和作用范围
    如何理解MVC?
    CSS3动画简介以及动画库animate.css的使用
    UGUI实现打字的效果
  • 原文地址:https://www.cnblogs.com/huyangblog/p/8571356.html
Copyright © 2020-2023  润新知