【Python3 笔记】Python3 函数式编程 高阶函数 返回函数 匿名函数 装饰器 偏函数

本系列是学习 廖雪峰 Python3 教程 过程中记录的笔记,本篇文章记录 Python 中的函数式编程,包括高阶函数(map() reduce() filter() sorted())、返回函数、匿名函数(lambda 表达式)、装饰器和偏函数。

函数式编程

  • 纯函数式编程:无变量;
  • 函数式编程特点:允许把函数本身作为参数传入另一个函数,允许返回一个函数;
  • Python 不是纯函数式编程语言,对其提供部分支持。

高阶函数

  • 函数本身也可以赋值给变量,即:变量可以指向函数;

  • 高阶函数:函数的参数变量中,有指向另外函数的变量,该函数便叫作高阶函数;

    f = abs
    print(f(-10))
    
    def add(x, y, f):
        return f(x) + f(y)
    
    print(add(-5, 8, abs))
    
    output—————————————
    10
    13
    
  • map(func, Iterable) 将某一种操作 func 应用于 Iterable每一个元素Iterable 是惰性序列,可以通过 list() 将所有元素计算出来并返回一个 List

  • reduce(func, Interable) 其中,func 必须接受2个参数,reduce 将结果继续和序列的下一个元素做累积计算;

    # 把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字
    def normalize(name):
        return name[0].upper() + name[1:].lower()
    
    L1 = ['adam', 'LISA', 'barT']
    L2 = list(map(normalize, L1))
    print(L2)
    # ------------------------------------------------------
    # 可以接受一个list并利用reduce()求积
    from functools import reduce
    def multiply(x, y):
        return x * y
    
    def prod(L):
        return reduce(multiply, L)
    
    print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
    if prod([3, 5, 7, 9]) == 945:
        print('测试成功!')
    else:
        print('测试失败!')
    # ------------------------------------------------------
    # 把字符串'123.456'转换成浮点数 123.456
    from functools import reduce
    DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    
    def char2num(s):
        return DIGITS[s]
    
    def str2float(s):
        s1, s2 = s.split(".")
        result1 = reduce(lambda x, y: x * 10 + y, list(map(char2num, s1)))
        result2 = reduce(lambda x, y: x * 10 + y, list(map(char2num, s2))) / 10 ** len(s2)
        result = result1 + result2
        return result
    
    print('str2float(\'123.456\') =', str2float('123.456'))
    if abs(str2float('123.456') - 123.456) < 0.00001:
        print('测试成功!')
    else:
        print('测试失败!')
        
    output————————————————
    ['Adam', 'Lisa', 'Bart']
    3 * 5 * 7 * 9 = 945
    测试成功!
    str2float('123.456') = 123.456
    测试成功!
    
  • filter(func, Iterable) func 返回布尔值,仅保留能够让 func 返回为真的 Iterable 的值,以此实现过滤的作用;

    def is_odd(n):
        return n % 2 == 1
    
    print(list(filter(is_odd, range(0, 10))))
    
    output—————————————
    [1, 3, 5, 7, 9]
    
  • sorted(list, keys, reverse) keys 指定排序规则,作用于每个元素上,reverse=Ture 可实现降序排序,默认为 False (升序);

    L = sorted(['aB', 'bob', 'about', 'Zoo', 'Credit'], key=str.lower)print(L)
    
    L1 = [('Bob', 88), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    
    def by_name(t):
        return t[0]
    
    def by_score(n):
        return n[1]
    
    L2 = sorted(L1, key=by_name)
    L3 = sorted(L1, key=by_score, reverse=True)
    print(L2)
    print(L3)
    
    output————————————
    ['aB', 'about', 'bob', 'Credit', 'Zoo']
    [('Adam', 92), ('Bart', 66), ('Bob', 88), ('Lisa', 88)]
    [('Adam', 92), ('Bob', 88), ('Lisa', 88), ('Bart', 66)]
    

返回函数

  • 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回;

  • 返回的函数不会立刻执行,等到它被调用时才会执行,返回函数可以使用局部变量 args ;

  • 返回闭包时,返回函数不要引用任何循环变量,或者后续可能会发生变化的变量。

    def createCounter():
        L = [0]
        def counter():
            L[0] +=1
            return L[0]
        return counter
    
    # 测试:
    counterA = createCounter()
    print(counterA(), counterA(), counterA(), counterA(), counterA())  # 1 2 3 4 5
    counterB = createCounter()
    if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
        print('测试通过!')
    else:
        print('测试失败!')
        
    output————————————
    1 2 3 4 5
    测试通过!
    

匿名函数

  • lambda x : x * 10 表示接收参数 x 返回 x*10 这就是匿名函数;

  • 匿名函数只能有一个表达式,: 是函数参数,可以有多个;

    def is_odd(n):
        return n % 2 == 1
    
    L = list(filter(is_odd, range(1, 20)))
    L1 = list(filter(lambda x: x % 2 == 1, range(1, 20)))
    print(L)
    print(L1)
    
    output——————————————
    [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
    [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
    

装饰器(Decorator)

  • 在代码的上方添加 @Decorator_function ,使得代码可以在运行期间动态添加功能,且不改变原有的功能,这种方式称之为装饰器;

  • 装饰器的本质是@Decorator_function 截获了被调用函数的逻辑控制流,它不会改变函数内部的逻辑,但装饰器可以控制调用流程,在函数执行前后添加指定的操作,例如打印日志信息等;

    import functools
    
    def metric(fn):
        @functools.wraps(fn)
        def wapper(*args, **kw):
            print("before start function ......")
            res = fn(*args, **kw)
            print("after end function ......")
            return res
        return wapper
    
    @metric
    def fast(x, y):
        print("000")
        return x + y
    
    @metric
    def slow(x, y, z):
        print("22200111")
        return x * y * z
    
    f = fast(11, 22)
    s = slow(11, 22, 33)
    print(f, s)
    if f != 33:
        print('测试失败!')
    elif s != 7986:
        print('测试失败!')
    
    output——————————————
    before start function ......
    000
    after end function ......
    before start function ......
    22200111
    after end function ......
    33 7986
    

偏函数

  • 当函数的参数过多时,可以使用functools.partial,把其中的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

    def int2(x, base=2):
        # base=N : 给定的 x 是 N 进制编码,默认是 10
        return int(x, base)
    
    print(int('12345'))
    print(int('1011', base=2))
    print(int2('1011'))
    
    output———————————————
    12345
    11
    11
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值