zoukankan      html  css  js  c++  java
  • 第二十四天

    函数式编程
    """
    函数式编程
    不是任何语言都能实现函数式编程。

    面向对象:解决类和类之间关系,解决工程的规范化。应对需求的不停改动的问题。
    函数式编程:一起去解决程序运行速度和单纯的数学公式的问题。
    """

    """
    函数和函数式编程。
    函数:定义一个函数,或者一个方法,完成某一项特定的功能。
    函数式编程:很多函数作用于一个输入上,给一个固定的输出。
    C(B(A(参数)))
    """
    # 鸟群合并 :合并:两个鸟群数量相加, 繁衍:两个鸟群相乘
    """
    a b c
    a和c先合并,再b繁衍
    a和b再进行繁衍
    再将上面两个大鸟群合并
    """
    # class Birds:
    # def __init__(self,n):
    # self.n=n
    # # 合并
    # # other代表另外一个鸟群
    # def conjoin(self,other):
    # self.n=self.n+other.n
    # return self
    # # 繁衍
    # def bread(self,other):
    # self.n=self.n * other.n
    # return self
    # bird_a=Birds(4)
    # bird_b=Birds(2)
    # bird_c=Birds(0)
    # # a和c先合并,再b繁衍4*2=8
    # # a和b再进行繁衍4*2=8
    # # 将两个大鸟群合并8+8=16
    # bird_1=bird_a.conjoin(bird_c).bread(bird_b)
    # bird_2=bird_a.bread(bird_b)
    # result=bird_1.conjoin(bird_2)
    # print(result.n)
    from operator import add, mul

    def conjoin(x, y):
    return x + y

    def bread(x, y):
    return x * y

    bird_a = 4
    bird_b = 2
    bird_c = 0

    result = conjoin(bread(conjoin(bird_a, bird_c), bird_b), bread(bird_a, bird_b))
    print(result)

    # 将原来的方法改成python固有的方法
    result = add(mul(add(bird_a, bird_c), bird_b), mul(bird_a, bird_b))
    print(result)

    # 结合律,交换律,分配律
    # add(add(x,y),z)==add(x,add(y,z))
    # add(x,y)==add(y,x)
    # mul(x,add(y,z))=add(mul(x,y),mul(x,z))
    result = add(mul(bird_a, bird_b), mul(bird_a, bird_b))
    mul(bird_a, add(bird_b, bird_b))
    print(result)

    # 函数式编程:首先要看输入,其次要尽量使用系统内部的方法,最后要尽量缩减整个函数

    # 几个相关的重要概念
    1. 头等函数:函数可以像变量一样,能够被赋值,能够被修改,能够被传递,能够被返回。
    如果支持函数式编程,需要函数必须是头等函数
    def e(a, b, **kwargs):
    return a * b

    print(type(e))

    2.匿名函数lambda:当函数体比较简单的时候,可以使用lambda表达式对函数进行提取
    lambda 参数: 返回值表达式
    def s(k):
    return k + 1

    f = lambda k: k + 1
    print(f(20))

    3.嵌套函数和闭包
    # def outer():
    # def inner():
    # pass
    # return inner()
    def outer():
    def inner():
    pass

    return inner

    # 计算一个数x的n倍
    def m(x, n):
    return x * n

    m(2, 3)
    m(5, 3)
    m(8, 3)

    def make_mul(n):
    def inner(x):
    return x * n
    return inner

    times3 = make_mul(3)
    times3(2)
    times3(5)
    time5 = make_mul(5)
    time5(2)

    # 高阶函数
    # 初阶函数:一阶函数
    # 高阶函数:至少满足下列条件中的一个:
    """
    1. 接受一个或者多个函数作为输入
    2. 输出一个函数
    """

    def make_mul(n):
    def inner(x):
    return x * n

    return inner

    time3 = make_mul(3)
    time5 = make_mul(5)
    # 函数调用可以看成从右到左
    time5(time3(2))

    # 使用可变类型的值传递,也可以达到高阶函数的效果
    def a(x):
    x += 1
    return list({1, x, 8})


    def b(y):
    y.append(100)
    return y

    print(b(a(4)))

    (一) 常见的高阶函数
    #
    1. sort
    li = [1, 3, -5, 7]


    def s(k):
    return abs(k)


    li.sort(key=s)
    print(li)
    li.sort(key=lambda k: abs(k))


    2. map 按函数规则改变元素
    map(fun,iterable)
    fun:函数的名字 iterable: 可迭代对象
    map可以将迭代对象中的每一个元素都按照fun函数进行执行,并返回。返回之后是一个迭代对象,
    只能遍历或者next
    def square(n):
    return n * n

    li = [1, 3, 5, 7, 9]
    result = map(square, li)
    print(result)
    # result.__next__()
    print(next(result))
    print(next(result))
    for i in result:
    print(i)

    3. filter 按照过滤条件,过滤每一个元素
    filter(fun,可迭代对象)
    对可迭代对象中的每一个元素,调用一次函数fun,将元素传入获得返回值
    对返回值是True的元素,则保留,否则删除
    f = filter(lambda n: n > 5, li)
    print(f)
    for i in f:
    print(i)
    4.reduce functools下的方法,按照函数二变一
    import functools

    functools.reduce(fun,可迭代对象)
    li = list(range(1, 11))
    # [1,2,3,4,5,6...10]
    # x=1 y=2
    # x=x+y=3
    # y=3
    # x=x+y=6
    # y=4
    # x=x+y=10
    # y=5

    最终得到一个结果,所以可以直接print
    print(functools.reduce(lambda x, y: x + y, li)) # li元素的累加和

    # 求元素的最大值
    print(functools.reduce(lambda x, y: x if x > y else y, li))

    5.max
    max(1, 2, 3, -6)
    max((2, 4, 5, 6))
    max(iterable,key)
    能够将每个元素应用key函数,获得返回值,取所有值中的最大值。
    year_cheese = [(2000, 35.1), (2001, 33.1), (2002, 33.4), (2003, 33.9)]
    print(max(year_cheese, key=lambda k: k[1]))

    (二)数据的不可变性
    """
    函数式编程是所有的输出都依赖于输入。要求同一个输入,永远得到同一个输出。
    要求函数式编程,严格控制数据的输入输出,所以在函数式编程中,
    一般选用元组或者命名元组作为输入和输出
    将传递进来的变量使用wrapper模式进行处理,变成不可变类型
    unwrap(process(wrap(参数)))
    """
    from toolz import second

    year_cheese = [(2000, 35.1), (2001, 33.1), (2002, 33.4), (2003, 33.9)]
    # (35.1,(2000,35.1))
    y = (2000, 35.1)
    l1 = map(lambda y: (y[1], y), year_cheese)
    # print(list(l1))
    print(max(map(lambda y: (y[1], y), year_cheese)))
    l2 = max(map(lambda y: (y[1], y), year_cheese))
    snd = lambda y: y[1]
    print(second(max(map(lambda y: (y[1], y), year_cheese))))

    # 函数式编程:将参数传入一个函数中,经过n函数,最后有一个输入
    # 而输入输出都是不可变的。

    # 纯函数/无副作用
    # 头等函数、嵌套函数、闭包、高阶函数------需要一个纯函数。
    # 纯函数:相同的输入,永远得到相同的输出,而且没有任何可观察的副作用。
    # 副作用:print sleep 调用了模块。
    # 为了达到纯函数的目的
    # 1. 只使用本地变量,避免声明全局变量
    x = 1

    def add(y):
    global x
    print(x + y)
    x += 1

    add(10)
    add(10)

    # 2.如果需要一个变量在作用域之外使用,可以使用闭包解决
    def add(y):
    x = 1
    print(x + y)
    x += 1

    add(10)
    add(10)

    # 纯函数的优点
    # 1.一个结果的目的能够是做缓存。
    # 2.可以进行移植
    # 3.类似于map作为高阶函数,只能接受纯函数,在使用并行计算时,会用到map

    # 引用透明度(纯函数)
    # 引用透明:返回值只依赖于输入值。

    operator模块
    """
    operator
    """
    from operator import *
    1. 算数运算
    a=1
    b=2
    # a+b
    print(add(a,b))
    print(mul(a,b))
    print(mod(a,b))

    2. 逻辑运算
    a=[1]
    b=[1]
    print(not_(a))
    print(is_(a,b))

    3. 比较,返回布尔类型
    a=3
    b=5
    for func in [lt,le,eq,ne,ge,gt]:
    print("{}(a,b)".format(func.__name__),func(a,b))
    # 效果等价
    print(lt(a,b))
    print(a<b)
    lt(a,b) #a<b
    le(a,b) #a<=b

    4.原地操作
    # add 和 iadd
    # iadd对不可变类型来说,作用add是一样
    a=3
    b=6
    iadd(a,b)
    print(a)
    # 对于可变类型来说iadd是原地增加
    a=[1,2,3]
    b=[4]
    # print(iadd(a,b))
    # print(a)
    iconcat(a,b)
    print(a)

    itertools模块
    """
    itertools:是python 内置模块
    """
    import itertools
    import operator
    1. 无限循环式迭代
    count(start,step)
    返回迭代器,获取均匀的间隔值,从传入的start开始,作为起始,step如果不写默认1
    for i in itertools.count(10):
    if i>15:
    break
    else:
    print(i)

    for i in itertools.count(10,1):
    if i>15:
    break
    else:
    print(i)

    2.cycle(iterator)
    创建一个循环遍历一些值的迭代器,产生迭代器
    count=0
    for i in itertools.cycle("xyz"):
    if count>5:
    break
    print(i)
    count+=1

    3.repeat(object,[time])
    返回重复的迭代器,永远返回同一个对象 ,可以通过time设置次数
    i=itertools.repeat(5,3)
    print(next(i))
    print(next(i))
    print(next(i))
    # print(next(i))

    按输入终止迭代
    1.itertools.accumulate 累积迭代器
    # 默认按照累加的结果
    # [1,2,3,4]
    # 1
    # 1+2
    # 1+2+3
    # 1+2+3+4
    print(list(itertools.accumulate(range(1,5))))

    # 可以指定 运算符
    print(list(itertools.accumulate(range(1,5),operator.mul)))

    2.groupby(iterable,key)
    # 把排好序的迭代对象,按照key中指定的函数,进行分组
    # 返回值中的每一个元素都是一个元组
    # 一定要先排序
    datas=[("A",111),("B",222),("C",333),("A",444),("C",555),("D",666)]
    datas_new=sorted(datas)
    print(datas_new)
    f=lambda x:x[0]
    for k,g in itertools.groupby(datas_new,f):
    # print(k,g)
    for m,n in g:
    print("{} is {}".format(m,n))

    3. tee(iterable,n) 从单个迭代器中创建n个同样的迭代器
    data="ABCDE"
    it1,it2,it3=itertools.tee(data,3)
    for i in it1:
    print(i)
    for i in it2:
    print(i)
    for i in it3:
    print(i)

    组合生成器
    1.itertools.combinations(iterable,r) r代表分组几个元素为一组
    print(list(itertools.combinations("WXYZ",3)))

    2.itertools.combinations_with_replacement 使用方式同上,包含重复的元素
    print(list(itertools.combinations_with_replacement("WXYZ",3)))

    3.product(*iterable,repeat=1)返回笛卡尔积
    # (1,2)*(4,5)=(1,4)(1,5)(2,4)(2,5)
    a=[(-1,1),(-3,3),(5,-5)]
    # -1,-3, -1,3 1,-3 1,3 *-5,5

    print(list(itertools.product(* a)))

    4. permutations 排列,其余跟itertools.combinations一样
    print(list(itertools.permutations("WXYZ",3)))

    functools模块
    """
    functools
    """
    from functools import partial
    from toolz import frequencies,compose
    1、 partial : 局部函数
    柯里化函数:在python就是局部函数
    使用函数的时候,只传递给函数一部分参数,调用后让他返回另外一个函数,去处理剩下的参数。
    # def fun(a,b):
    # pass
    # x=fun(a)
    # x(b)
    # fun(a,b)
    #n倍乘,闭包
    # def mul(n,x):
    # # return n*x
    # # 希望只传入n获得函数。
    # def mulfun(n):
    # def inner(x):
    # return n*x
    # return inner
    # times3=mulfun(3)
    # times3(10)

    # mulfun(3,10)
    # partial可以解决函数柯里化的问题
    新函数=partial(原函数,一个参数)
    新函数(另外一个参数)
    等价于:原函数(一个参数,另外一个参数)
    def mul(n,x):
    return "{}*{}={}".format(n,x,n*x)
    #3倍乘法,n=3
    time3=partial(mul,3)
    print(time3(10))

    # 传递参数的时候,如果不传入命名关键字参数,那么传入参数按照第一个位置参数来赋值。
    # 已知x=10
    x10=partial(mul,x=10)
    print(x10(3))

    # 安装toolz模块:后台,执行pip install toolz

    # 需求:统计字符串中每一个英文单词出现的次数:
    # A friend in need is a friend indeed.
    # 思路:
    """
    1. 使用空格分隔出每一个单词
    2. 去掉每一个单词前后的特殊符号
    3. 将所有的字符小写
    4. 统计
    """
    temp_str="A friend in need is a friend indeed."
    # 按照空格分隔
    li=temp_str.split(" ")
    print(li)
    # 使用map能够处理每一个元素,能用for解决的问题用map解决
    # map(fun,iterable)
    def stem(word):
    return word.lower().rstrip(".!,").lstrip(".!,")
    print(list(map(stem,li)))

    使用frequencies计算频次
    print(frequencies(map(stem,li)))

    # 尝试柯里化函数解决
    map_new=partial(map,stem)
    result=map_new(temp_str.split(" "))
    print(list(map_new(temp_str.split(" "))))
    print(frequencies(map_new(temp_str.split(" "))))

    # compose:组合函数
    # compose(f1,f2,f3) 从右到左
    # 组合的结果会返回新的函数。
    # f1(f2(f3(参数)))
    wordcount=compose(frequencies,partial(map,stem),str.split)
    print(wordcount(temp_str))

    # 练习
    # pow(x,y)
    # 1.自己重新实现以下power函数
    # 2.通过局部函数的形式调用



  • 相关阅读:
    【计算机视觉】行人检测(Pedestrian Detection)资源
    【计算机视觉】图像处理与计算机视觉基础,经典以及最近发展
    【计算机视觉】图像处理与计算机视觉基础,经典以及最近发展
    【计算机视觉】期刊整理
    【计算机视觉】期刊整理
    【计算机视觉】TPAMI的Editors
    【计算机视觉】TPAMI的Editors
    匈牙利命名法收藏
    匈牙利命名法收藏
    【计算机视觉】计算机视觉/图像/模式识别方向期刊会议
  • 原文地址:https://www.cnblogs.com/ztx695911088/p/9490701.html
Copyright © 2011-2022 走看看