zoukankan      html  css  js  c++  java
  • Python学习笔记 -- 第四章

    高阶函数

    变量可以指向函数

    f=abs
    f(-10)
    10
    变量f指向abs函数,直接调用abs()函数和调用f()完全相同

    传入参数

    变量可以指向函数,函数的参数可以接收另一个函数的参数,这种函数成为高阶函数。

    def add (x,y,y):
    return f(x) + f(y)

    当调用add(-5,6,abs)时,参数x,y,z分别接收-5,6和abs,计算过程如下:

    x = -5
    y = 6
    f = abs
    f(x) + f(y) > abs(-5)+abs(6)> 11
    retutn 11

    函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。

    map函数

    map()函数接收两个参数,一个是函数,另一个是literable,map将传入的函数依次作用刀序列的每一个元素,并作为新的literable返回。

    def f(x)
    return x * x
    ....
    r = map(f,[1,2,3,4,5,6,7,8,9])
    list(r)
    [1,4,9,16,25,36,49,64,81]

    reduce函数

    reduce把一个函数作用到一个序列[x1,x2,x3,...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算:
    reduce(f,[x1,x2,x3,x]) = f(f(f(x1,x2),x3),x4)
    比如求一个序列的和

    from functools import reduce
    def add(x,y):
    return x + y
    ...
    reduce(add,[1,3,5,7,9])
    25 #求和运算可以直接用sum

    如果把序列[1,3,5,7,9]变成整数13579,

    for functools import reduce
    def fn(x,y):
    return x * 10 + y
    ....
    reduce(fn,[1,3,5,7,9])
    13579

    把str转int的函数

    from functools import reduce
    def str2int(s):
    return x * 10 + y
    def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn,map(char2num,s))

    用lambda函数继续简化

    from functools import reduce
    def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

    filter函数

    和map()类似,filter()也可接收一个函数和一个序列。filter()把传入的函数依次作用于每一个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

    def is_odd(n):
    return n % 2 == 1
    list(filter(is_odd,[1,2,4,6,9,10,15])) #删除list中的偶数

    结果是:[1,5,9,15]

    sorted函数

    sorted函数用于对list进行排序。

    sored([2,5,1,6,4,9])
    [1,2,4,5,6,9]

    sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序。

    sorted([36, 5, -12, 9, -21], key=abs)
    [5, 9, -12, -21, 36]

    对于字符串排序

    sorted(['bob', 'about', 'Zoo', 'Credit'])
    ['Credit', 'Zoo', 'about', 'bob'] #按照ASCLL大小比较

    忽略大小写

    sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
    ['about', 'bob', 'Credit', 'Zoo']

    反向排序

    sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
    ['Zoo', 'Credit', 'bob', 'about']

    返回函数

    定义一个可变参数的求和

    def calc_sum(*args):
    ax = 0
    for n in args:
    ax = ax + n
    return ax

    不需要立即求和,在后面的代码中调用

    def lazy_sum(*args):
    def sum():
    ax = 0
    for n in args:
    ax = ax + n
    return ax
    return sum

    当调用lazy_sum()时,返回的不是求和结果,而是求和函数,调用函数f时,才是计算结果。
    函数lazy_sum中定义了函数sum,并且内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都存在返回函数中,这种称为”闭包“

    一个函数可以返回一个计算结果,也可以返回一个函数。
    返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

    匿名函数

    list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    [1, 4, 9, 16, 25, 36, 49, 64, 81]

    匿名函数lambda x: x*x就是

    def f(x)
    return x * x
    关键字lambda表示匿名函数,冒号前面的x表示函数参数,匿名函数只能有一个表达式,不用写return,不用担心函数名冲突。

    把匿名函数赋值给一个变量,再利用变量来调用该函数:

    f = lambda x: x * x
    f(5)
    25

    把匿名函数作为返回值返回

    def build(x, y):
    return lambda: x * x + y * y

    装饰器

    (未看明白)

    偏函数

    int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

    int('12345')
    12345

    int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:

    int('12345', base=8)
    5349
    int('12345', 16)
    74565

    要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:

    def int2(x, base=2):
    return int(x, base)

    functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

    import functools
    int2 = functools.partial(int,base = 2)
    int2('1000000')
    64

    functools.partial的作用:把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

    创建偏函数时,可以接收函数对象,*args和**kw这三个函数,当传入
    int2 = functools.partial(int, base=2)时,固定的int()函数关键字参数base

    当传入max = functools.partial(max,10)
    会把10作为*args的一部分自动加到左边,也就是
    max2(5,6,7)相当于 max(10,5,6,7)

    小结

    当函数参数的个数太多,需要简化时,使用functools.partial可以创建一个新函数,新函数可以固定原函数的部分参数,使函数调用更简单。

  • 相关阅读:
    Mybatis 的 xml 文件语法错误,启动项目时控制台一直循环解析但是不打印错误
    在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
    【Important】数据库索引原理
    服务化的演变和负载均衡
    【问题集】redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
    【Spring】Spring中用到的设计模式
    【设计模式】责任链模式
    【!Important】Zookeeper用来做什么的,有几种类型的节点
    【!Important】如何保证线程执行的先后顺序
    【!Important】Java线程死锁查看分析方法
  • 原文地址:https://www.cnblogs.com/battleblock/p/4827604.html
Copyright © 2011-2022 走看看