Python函数式编程

                                                    Python函数式编程
Python版本:3.6.5
1、高阶函数
    (1)、map/reduce:Python内建了map()和reduce()函数
        1)、map: map接收2个参数,1个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
            1]、例如:要打印出一个结果类似于 x^2 的list :我们可以先定义一个函数,然后把这个函数作为第一个参数传入map,第二个参数传这个函数的部分实参的集合list。
                代码:
                    def x_sqrt(x):
                        return x*x

                    result = map(x_sqrt, [1,2,3,4,5])
                    print(list(result))
                打印:
                    [1, 4, 9, 16, 25]
                
                解释:map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是[惰性序列],因此通过list()函数让它把整个序列都计算出来并返回一个list。
                扩展:把任意list数字转为字符串
                    代码:print(list(map(str,[2,3,565,878])))
                    打印:['2', '3', '565', '878']
        2)、reduce:再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
            其效果就是:
            reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
            1]、list求和:需要从functools中引入reduce方法
                代码:
                    from functools import reduce
                    def add(x,y):
                        return x+y

                    result = reduce(add, [1,2,3,4])
                    print(result)
                打印:
                    10
            2]、要把序列 [1,2,3,4] 变成 1234 :
                1.我们可以这样写:
                    代码:
                        from functools import reduce
                        def add(x,y):
                            return x*10+y

                        result = reduce(add, [1,2,3,4])
                        print(result)
                2.还可以配合map把字符串 '1234'变成 1234
                    from functools import reduce
                    def add(x,y):
                        return x*10+y

                    def strToInt(str):
                        dicts = {'1':1,'2':2,'3':3,'4':4}
                        return dicts[str]

                    result = reduce(add, map(strToInt, '1234'))
                    print(result)
                都打印:
                    1234
        3)、filter: 和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数循环传入的于每个元素,然后保留为True结果,丢弃为False的结果。
            1]、返回一个序列中为3的倍数的值
                代码:
                    def threeN(x):
                        return x % 3 == 0

                    print(list(filter(threeN,[1,2,3,4,5,6,7,8,9])))
                打印:
                    [3, 6, 9]
                分析: filter()函数能够“筛选”出正确的值。并且filter()函数返回的也是一个Iterator惰性序列,需要用list()函数来返回结果集。
        4)、排序算法:
            1]、sorted()函数就可以对list进行排序
                代码:print(sorted([3,-34,324,2]))
                打印:[-34, 2, 3, 324]
            2]、定义一个key参(函)数,按绝对值大小排序:key指定的函数会调用list的每一个元素,sorted根据key函数返回的结果进行排序。
                代码:print(sorted([3,-34,324,2], key=abs))
                打印:[2, 3, -34, 324]
            3]、字符串排序
                1.默认排序
                    代码:
                        nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
                        result = sorted(nameArr)
                        print(result)
                    打印:
                        ['LiuLiu', 'Zhangsan', 'liSi', 'wangWu']
                    分析:
                        ASCII 中大写字母为65 小写字母为97,所以大写字母在小写字母之前。
                2.忽略字母大小写排序:先把list全部转为大写 str.upper() 或小写 str.lower(),然后按从小到大排序
                    代码:
                        nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
                        result = sorted(nameArr, key=str.lower)
                        print(result)
                    打印:
                        ['liSi', 'LiuLiu', 'wangWu', 'Zhangsan']
                3.把结果按从大到小排列,按照方法2,再给函数加上第三个参数 reverse=True
                    代码:
                        nameArr = ['Zhangsan', 'liSi', 'wangWu', 'LiuLiu']
                        result = sorted(nameArr, key=str.lower, reverse=True)
                        print(result)
                    打印:
                        ['Zhangsan', 'wangWu', 'LiuLiu', 'liSi']
                        
2、返回函数
    (1)、案例:返回一个计算累加和的函数
        代码:
            def cacl_total(*args):
                def sum():
                    cnt = 0
                    for n in args:
                        cnt += n
                    return cnt
                return sum

            ret = cacl_total(1,2,3,4)    #当我们调用cacl_total()时,返回的并不是求和结果,而是求和函数
            print(ret)                    #调用函数 ret 时,才真正计算求和的结果
            print(ret())
        打印:
            <function cacl_total.<locals>.sum at 0x04BB8150>
            10
        分析:
            1]、我们 在函数 cacl_total 中又定义了 一个函数 sum ,sum内部函数可以获取函数 cacl_total 的参数和局部变量。
                当我们调用 cacl_total 时,相关参数和变量都保存在返回的函数中。这就称为“闭包”程序。
            2]、每次调用 cacl_total 返回的都是一个新的函数,即使传入相同的值,返回的函数还是不同的,互不影响。
    (2)、闭包函数:注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。
        1)、返回的函数并没有立刻执行,而是直到调用了f()才执行
            代码:
                def count():
                    fs = []
                    for i in range(1, 4):
                        def f():
                             return i*i
                        fs.append(f)
                    return fs

                f1, f2, f3 = count()
                print(f1())
                print(f2())
                print(f3())
            打印:
                9
                9
                9
            原因:原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
        2)、 非要打印 1 4 9 :再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变
            代码:
                def count():
                    def f(j):
                        def g():
                            return j*j
                        return g
                    fs = []
                    for i in range(1, 4):
                        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
                    return fs

                f1, f2, f3 = count()
                print(f1())
                print(f2())
                print(f3())
                
3、匿名函数:关键字 lambda 冒号分开 加表达式  =>   lambda : x*x
    (1)、代替之前的函数 x*x
        代码:print(list(map(lambda x: x*x, [1,2,3,4])))
        打印:[1, 4, 9, 16]
    (2)、变量接收,变量调用
        代码:     f = lambda x: x*x
                print(f(45))
        打印:2025
    (3)、把匿名函数作为返回值返回    lambda : x*y
        代码:
            def test(x,y):
                    return lambda : x*y
                
                ret = test(3,7)
                print(ret)
                print(ret())
        打印:
            <function test.<locals>.<lambda> at 0x036C8150>
            21


4、偏函数:通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点
    (1)、 int() 函数把字符串转为整数,并提供额外的base参数,默认值是10,如果传base参数,就可以进行N进制的转换
        print(int('1234',base=8))
        print(int('1234',8))
        输出:668    668
    (2)、假设要转换许多二进制字符串,可以封装一个函数给默认值
        def intTo2(x, base=2)
            return int(x,base)
        我们可以不定义 intTo2:
            import functools
            intTo2 = functools.partial(int,base=2)
            print(intTo2('100000'))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值