python学习笔记9:函数式编程

函数式编程(FunctionalProgramming)

  • 基于lambda演算的一种编程方式

    • 程序中只有函数
    • 函数可以作为参数,同样可以作为返回值
    • 纯函数式编程语言: LISP, Haskell
  • Python函数式编程只是借鉴函数式编程的一些特点,可以理解成一半函数式一半Python
  • 需要理解
    • 高阶函数
    • 返回函数
    • 匿名函数
    • 装饰器
    • 偏函数

lambda表达式

  • 函数: 最大程度复用代码

    • 存在问题: 如果函数很小,很短,则会造成啰嗦
    • 如果函数被调用次数少,则会造成浪费
    • 对于阅读者来说,造成阅读流程的被迫中断
  • lambda表达式(匿名函数):
    • 一个表达式,函数体相对简单
    • 不是一个代码块,仅仅是一个表达式
    • 可以有参数,有多个参数也可以,用逗号隔开
      # lambda表达式的用法
      # 1. 以lambda开头
      # 2. 紧跟一定的参数(如果有的话)
      # 3. 参数后用冒号和表达式主题隔开
      # 4. 只是一个表达式,所以,没有return
      # 5. 使用 的时候以函数的方式使用fun(v1,v2....)
      # 计算一个数字的100倍数
      # 因为就是一个表达式,所以没有return
      stm = lambda x: 100 * x 
      # 使用上跟函数调用一模一样
      stm(89)

高阶函数

  • 把函数作为参数使用的函数,叫高阶函数
  • 函数名称是变量,则应该可以被当做参数传入另一个函数
    def aa(n):
    return n*10
    def bb(n,f):
    return f(n)*3
    bb(3,aa)

    系统高阶函数-map

  • 原意就是映射,即把集合或者列表的元素,每一个元素都按照一定规则进行操作,生成一个新的列表或者集合
  • map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
  • map(函数,要处理的列表)
    • map(lambda x:x*10,[i for i in range(10)] )

reduce

  • 原意是归并,缩减,把一个可迭代对象最后归并成一个结果
  • reduce 需要导入functools包:from functools import reduce
  • 对于作为参数的函数要求: 必须有且仅有两个参数,必须由返回结果
  • reduce([1,2,3,4,5]) == f( f(f(f(1,2),3), 4),5)
    • rst = reduce( lambda x,y:x+y, [1,2,3,4,5,6] )

filter 函数

  • 过滤函数: 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
  • 跟map相比较:
    • 相同:都对列表的每一个元素逐一进行操作
    • 不同:
      • map会生成一个跟原来数据想对应的新队列
      • filter只有符合条件的才会进入新的数据集合
    • filter函数用法:
      • 利用给定函数进行判断,过滤函数返回值一定是个布尔值
      • 调用格式: filter(f, data), f是过滤函数, data是数据,返回一个可迭代的filter对象
      • rst = filter(lambda x:x%2==0, [1,3,4,5,8,9])

sort-排序

  • 把一个序列按照给定算法进行排序
  • key: 在排序钱对每一个元素进行key函数运算,可以理解成按照key函数定义的逻辑进行排序
  • python2 和 python3 相差巨大
  • key: key=abs绝对值, key=str.lower:小写。。。。

返回函数

  • 把一个函数当做返回值返回
    # 返回函数的例子
    # args:参数列表
    # 1 myF4定义函数,返回内部定义的函数myF5
    # 2. myF5使用了外部变量,这个变量是myF4的参数
    def myF4( *args):
    def myF5():
        rst = 0
        for n in args:
            rst += n
        return rst
    return myF5
    # 执行
    f5 = myF4(1,2,3,4,5,6,7,8,9,0)
    f5()

闭包(closure)

  • 当一个函数在内部定义函数,并且内部的函数使用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结果,叫闭包
  • 上面定义的myF4是一个标准闭包结构
    # 闭包常见坑
    def count():
    # 定义列表,列表里存放的是定义的函数
    fs = []
    for i in range(1,4):
        # 定义了一个函数f
        # f是一个闭包结构
        def f():
            return i*i
        fs.append(f)
    return fs
    f1,f2,f3 = count()
    #期望出现,1,4,9实际是9,9,9,

    出现的问题:

  • 造成上述状况的原因是,返回函数引用了变量i, i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都返回的是 3*3
  • 此问题描述成:返回闭包时,返回函数不能引用任何循环变量
  • 解决方案: 再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不再改变

装饰器(Decrator)

  • 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
  • 装饰器的使用: 使用@语法, 即在每次要扩展到函数定义前使用@+函数名
  • 实际上是在函数具体执行之前,执行装饰器里面的内容
    import time
    # 高阶函数,以函数作为参数
    def printTime(f):
    def wrapper(*args, **kwargs):
        print("Time: ", time.ctime())
        return f(*args, **kwargs)
    return wrapper
    @printTime
    def add(x,y):
    return x+y
    print(add(77,44))

    偏函数

  • 参数固定的函数,相当于一个由特定参数的函数体
  • functools.partial的作用是,把一个函数某些函数固定,返回一个新函数
    import functools
    #实现上面int16的功能
    int16 = functools.partial(int, base=16)
    int16("12345")

高级内置函数

zip

  • 把两个可迭代内容生成一个可迭代的tuple元素类型组成的内容,如果元素不对等,取能匹配的最大值
    # zip 案例
    l1 = [ 1,2,3,4,5]
    l2 = [11,22,33,44]
    z = zip(l1, l2)
    for i in z:
    print(i)
    #输出
    (1, 11)
    (2, 22)
    (3, 33)
    (4, 44)

    enumerate

  • 跟zip功能比较像
  • 对可迭代对象里的每一元素,配上一个索引,然后索引和内容构成tuple类型
    l1 = [11,22,33,44]
    em = enumerate(l1)
    l2 = [i for i in em]
    print(l2)
    #输出:
    [(0, 11), (1, 22), (2, 33), (3, 44)]

    collections模块

    namedtuple

  • 是一个可命名的tuple
    import collections
    Point = collections.namedtuple("Point", ['x', 'y'])
    p = Point(11, 22) 

    deque

  • 比较方便的解决了频繁删除插入带来的效率问题
    from collections import deque
    q = deque(['a', 'b', 'c'])
    q.append("d")
    q.appendleft('x')
    ## deque(['x', 'a', 'b', 'c', 'd'])

    defaultdict

  • 当直接读取dict不存在的属性时,直接返回默认值
  • 第一个参数要为函数
  • func = lambda: "刘大拿"
    d2 = defaultdict(func)

    Counter

  • 统计字符串个数

```c = Counter("abcdefgabcdeabcdabcaba")
print(c)
s = ["liudana", "love", "love", "love", "love", "wangxiaona"]
c = Counter(s)

转载于:https://blog.51cto.com/14083201/2338419

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值