zoukankan      html  css  js  c++  java
  • python学习22之函数式编程

    ''''''
    '''
    1.高阶函数:将函数作为参数传递到另一个函数中,作为这个函数的参数,这样的方式叫高阶函数
    (1)map:两个参数,一个是函数,一个是iterator,将函数依次作用于Iterator中的每一个元素,结果返回一个Iterator
    '''
    #高阶函数举例
    a=abs(-10) #abs()是python内置的取绝对值的函数
    print(a)
    f=abs #将函数abs本身赋值给变量f,也可以理解为将函数abs的函数名更改为f,这样就可以调用f来取代abs的功能
    b=f(-10)
    print(b)
    #10
    def add(x,y,f):
    return f(x)+f(y)
    s=add(-5,6,abs)
    print(s)
    #当我们调用add(-5, 6, abs)时,参数x,y和f分别接收-5,6和abs,根据函数定义,我们可以推导计算过程为:f(x) + f(y) ==> abs(-5) + abs(6) ==>11

    #map
    def f(x):
    return x*x
    L=map(f,[1,2,3,4,5,6])
    print(L)
    #<map object at 0x00000173F1012358> map()传入的第一个参数是f,即函数对象本身。由于结果L是一个Iterator(map),Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
    print(list(L))
    #[1, 4, 9, 16, 25, 36]

    L1=list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    print(L1)
    #['1', '2', '3', '4', '5', '6', '7', '8', '9']

    '''
    (2)reduce函数:它把一个函数作用在一个序列[x1, x2, x3, ...]上,
    这个函数必须接收两个参数,比如参数函数f作用是乘积操作,reduce会把结果继续和序列的下一个元素做f乘积计算,其效果就是:
      reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    注意使用时先导包:from functools import reduce
    '''
    from functools import reduce
    #应用:对一个数列(1到100的列表)求和
    def add(x,y):
    return x+y
    L2=[]
    for i in range(1,101):
    L2.append(i)
    sum=reduce(add,L2)
    print(sum)

    def normalize(LST):
    # def lower(s):
    # return s.lower() #全部小写函数 upper()全部大写函数

    def capitalize(s):
    return s.capitalize() #首字母大写函数,其余小写

    return map(capitalize,LST)
    L=['adam', 'LISA', 'barT']

    r=normalize(L)
    print(list(r))

    '''
    (3)filter:Python内建的filter()函数用于过滤序列。
    filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

    '''
    def odd(i):
    return i%2 != 0
    li=[]
    for i in range(1,101):
    li.append(i)
    li2=list(filter(odd,li))
    print(li2)

    #应用:用filter求素数
    def _odd_iter(): #创建一个从3开始的初始序列
    n = 1
    while True:
    n = n + 2
    yield n

    '''
    yield:
    作用:首先起到return的作用,函数结束,返回结果
    其次起到生成器的作用:在Python中,这种一边循环一边计算的机制,称为生成器:generator。
    最后带yield的函数才是真正的迭代器。
    '''
    g = (x * x for x in range(10))
    #g就是一个生成器,我们想要得到g的每一个值,可以通过next()函数获得generator的下一个返回值:
    print(next(g))
    print(next(g))
    print('*'*50)
    #generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
    #如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
    #generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
    #可以直接作用于for循环的对象统称为可迭代对象:Iterable.可以使用isinstance()判断一个对象是否是Iterable对象:
    #而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
    #可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
    def _not_divisible(n):
    return lambda x: x % n > 0 #筛选函数
    def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
    n = next(it) # 返回序列的第一个数
    yield n
    it = filter(_not_divisible(n), it) # 构造新序列
    # 打印100以内的素数:
    for n in primes():
    if n < 100:
    print(n)
    else:
    break
    '''
    (4)sorted():
    '''
    #升序排列
    L=[11,-15,22,9,35,-1,-5,79]
    print(sorted(L))
    #降序排列
    print(sorted(L,reverse=True))
    #可以当做高阶函数,传入函数为参
    print(sorted(L,key=abs)) #按照绝对值大小去比较
    #假设我们用一组tuple表示学生名字和成绩,请用sorted()对上述列表分别按名字排序
    L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    def by_name(t):
    return t[0]
    print(sorted(L,key=by_name))
    #再按成绩从高到低排序
    def by_score(t):
    return t[1]
    print(sorted(L,key=by_score))
    '''
    2.返回函数——闭包
    在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,
    这种称为“闭包(Closure)”的程序结构拥有极大的威力。
    '''
    def lazy_sum(*args):
    def sum():
    ax = 0
    for n in args:
    ax = ax + n
    return ax
    return sum
    f=lazy_sum(1,2,3,4,5,6)
    print(f)
    print(f())
    '''
    <function lazy_sum.<locals>.sum at 0x0000020C2F455730>
    21
    '''
    #利用闭包返回一个计数器函数,每次调用它返回递增整数。
    def createCounter():
    m = 0
    def counter():
    nonlocal m
    m += 1
    return m
    return counter
    cnt=createCounter()
    print(cnt())
    print(cnt())
    print(cnt())
    '''
    global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,
    而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误

    global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global修饰后也可以直接使用,
    而nonlocal关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误
    '''
    '''
    3.匿名函数
    4.装饰器:在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
    5.偏函数:functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
    '''
  • 相关阅读:
    Python编程题24--回文数
    Python编程题23--移动零
    Python编程题22--只出现一次的数字
    Python编程题21--每日温度
    Python编程题20--最大子序和
    Python编程题19--比特位计数
    推荐系统中对比实验工具--伯乐bole
    pytorch中反向传播的loss.backward(retain_graph=True)报错
    win10彻底禁止自动更新(家庭版操作)
    linux使用清华源安装工具,切换清华源
  • 原文地址:https://www.cnblogs.com/wsxcode/p/12570315.html
Copyright © 2011-2022 走看看