zoukankan      html  css  js  c++  java
  • Python3 函数式编程自带函数

    一 map函数

    引子

    需求1:num1=[1,2,3,4],我的需求是把num1中的每个元素平方后组成新列表。

    ret = []
    num1 = [1,2,3,4]
    for i in num1:
        ret.append(i**2)
    
    print(ret)
    
    # 输出结果:
    >>>[1, 4, 9, 16]
    

    需求2:如果有1万个列表呢,怎么办?

    思路:如果用for循环,当然功能上是没问题的,但是需要写很多重复代码,重复代码?? 顿时想到函数的特性就是避免重复代码,哈哈哈,天才也....

    num1 = [1,2,3,4]
    def foo(array):
        ret = []
        for i in array:
            ret.append(i**2)
        return ret
    print(foo(num1))
    
    """
    每个列表调用1次函数即可,一万个列表调用1万次foo函数就行了,不用写一万个for循环,问题解决。
    """
    
    # 输出结果:
    >>>[1, 4, 9, 16]    

    需求3:如果1万个列表,同时需要每个元素自加1,自减1,自乘1,自平方...???

    思路:看到题目就在想,你是猴子派来玩我的吗??? 如果安装2中的方法,我去,需要一个功能一个函数,这真的可以吗? 当然不行,这样太out了...

    def add_one(x):          # 定义自加一处理逻辑
        return x+1
    def reduce_one(x):      # 定义自减一处理逻辑
        return x-1
    def plus_one(x):        # 定义自平方处理逻辑
        return x**2
    
    
    def map_test(func,array):
        ret = []
        for i in array:
            res = func(i)   # 相当于 res = add_one(i)
            ret.append(res)
        return ret
    
    print(map_test(add_one,[1,2,3,4]))
    
    # 运行结果
    >>>[2, 3, 4, 5]  

    突发奇想:3中的代码在定义处理逻辑的时候,不就是lambda的处理方式吗,可不可以使用lambda代替呢??答案是肯定的。

    def map_test(func, array):
        ret = []
        for i in array:
            res = func(i)
            ret.append(res)
        return ret
    
    print(map_test(lambda x:x+1,[1,2,3,4]))
    
    # 输出结果
    >>> [2, 3, 4, 5]
    

    哈哈,完美了...

    此时我正沉浸在胜利的喜悦中,一个声音让我一下从天堂坠入地狱...

    A:这个代码好臃肿啊,一行代码能完成的事情,为什么要写成这样呢???

    我(心想):一行???吹呢吧,你要是能写,我拜你为师....

    A:我告诉你吧,你的处理思维是没错的,但是Python自带的map函数完全可以替代你的上述代码,简单的很呦!!

    print(map(lambda x:x+1,[1,2,3,4]))
    # <map object at 0x0000000000597390>  map处理后得到的结果就是一个迭代器.
    print(list(map(lambda x:x+1,[1,2,3,4])))
    
    # 运行结果
    >>> [2, 3, 4, 5]
    # list函数可以把可迭代的对象变成列表
    
    """
    map函数总结:
    lambda x:x+1 (第一个参数)处理逻辑,不一定必须使用lambda
    [1,2,3,4] (第二个参数)要处理的可迭代对象
    """
    
    # 把字符串中的每个元素变成大写
    msg = 'abcd'
    print(list(map(lambda x:x.upper(),msg)))
    
    # 运行结果
    >>> ['A', 'B', 'C', 'D']  

    什么也不说了,师傅,请受徒儿一拜.....,抬头望去,人了??哎,高人就是不一样啊.....

    二 filter函数

    需求1:电影院中有5个人在看电影,筛选出他们的名字前面不含sb字符的人

    movie_people = ['sb_a','sb_b','sb_c','d','e']
    ret = []
    for p in movie_people:
        if not p.startswith('sb'):
            ret.append(p)
    
    print(ret)
    
    # 打印结果
    >>> ['d', 'e']:

    需求2:电影院中有5个人在看电影,筛选出他们的名字前后不含sb字符的人

    movie_people = ['sb_a','sb_b','sb_c','d','e']
    
    def sb_show(n):
        return n.startswith('sb')
    def show_sb(n):
        return n.endstwith('sb')
    
    def filter_test(array,func):
        ret = []
        for p in array:
            if  not func(p):
                ret.append(p)
    
        return ret
    
    print(filter_test(movie_people,sb_show))
    
    # 运行结果
    >>> ['d', 'e']

    终极版本:使用lambda代替上述代码中的show_sb和sb_show函数。

    def filter_test(array,func):
        ret = []
        for p in array:
            if  not func(p):
                ret.append(p)
    
        return ret
    
    print(filter_test(movie_people,lambda x:x.startswith('sb')))
    
    # 运行结果
    >>> ['d', 'e'] 

    使用自带函数filter完成

    movie_people = ['sb_a','sb_b','sb_c','d','e']
    print(list(filter(lambda x:not x.startswith('sb'),movie_people)))
    
    """
    filter说明:
    第一个参数:处理逻辑,结果必须是一个布尔值
    第二个参数:要处理的可迭代的内容
    """

    三 reduce函数

    reduce函数在Python2中可以直接使用,在Python3中需要引用(from functools import reduce)。

    • 处理一个序列,然后把序列中的每个元素进行合并(相加、相乘等)操作。

    实例(Python3.0+):

    num_1 = [1,2,3,4]
    from functools import reduce
    print(reduce(lambda x,y:x+y,num_1,10))
    
    # 运行结果
    >>> 20
    
    """
    第一个参数:处理逻辑
    第二个参数:可迭代对象
    第三个参数:初始值,如果有初始值,会把初始值也进行合并
    """

    四 函数对照表

    需求:有一个列表,筛选出age小于1000的人

    思路:此需求中是要过滤age小于1000的人,三个函数中可以选择filter()

    people = [
        {'name':'alex','age':1000},
        {'name':'wupeiq','age':10000},
        {'name':'linhaifeng','age':18}
    ]
    
    print(list(filter(lambda x:x['age'] < 1000,people)))
    
    # 运行结果
    >>> [{'age': 18, 'name': 'linhaifeng'}]
    

       

  • 相关阅读:
    robotframework +selenium 自动化测试之浏览器与驱动的兼容问题。
    robotframework+selenium自动化robotramework版本问题
    一个业务逻辑引发的对多表连接的思考
    第一次接触WebSocket遇到的坑以及感受
    关于读写APP.config文件能读却写不了的问题
    poj2392 space elevator
    洛谷P1197 星球大战
    poj3421&poj3292&poj2689 基础数论
    洛谷P1006 传纸条
    挑战程序设计竞赛2.3节习题选解
  • 原文地址:https://www.cnblogs.com/lvcm/p/9264166.html
Copyright © 2011-2022 走看看