• Python学习3(函数、装饰器)


    千峰教育b站的课程

    函数

    函数定义

    参数可有可无

    def 函数名([参数...]):
        代码
    
    • 1
    • 2

    直接打印函数名,会看到函数所在的内存地址,函数名相当于一个变量,指向了这个内存地址

    def gen():
        print(1)
    print(gen) # <function gen at 0x000002B1092DC268>
    
    • 1
    • 2
    • 3

    调用,函数名()

    调用函数时参数的顺序

    >>> def test(a,b):
    ...     print(a,b)
    ... 
    >>> test(1,2)  # 位置参数
    1 2
    >>> test(b=1,a=2)  # 关键字参数
    2 1
    >>> 
    >>> test(b=1,2)  # 关键字参数写在位置参数之前会导致出错
      File "<stdin>", line 1
    SyntaxError: positional argument follows keyword argument
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    怎么保证传入的参数符合类型要求
    isinstance(变量, 类型)

    def get_sum(a,b):
        if isinstance(a, int) and isinstance(b, int):
            print(a + b)
        else:
            print('type error')
    get_sum(1.2,2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数默认值

    在定义参数的时候可以给参数赋默认值,这样在调用的时候可以不传递这个参数
    且默认值参数必须在普通参数的后面(其实也很好理解,因为调用函数传递的时候是按位置传递的)

    # def get_sum(a, c = 100,b): # 报错
    def get_sum(a,b, c = 100): # c给定了默认值100
        if isinstance(a, int) and isinstance(b, int):
            print(a + b + c)
        else:
            print('type error')
    get_sum(1,2) #103
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    关键字参数

    调用的时候明确使用参数名赋值,因为默认是按位置顺序赋值的,为了防止因为位置传递发生错误,可以使用关键字参数赋值
    例如下面例子中,如果c想用默认值,而d要传递参数,就需要用到关键字参数

    def get_sum(a,b, c = 100,d=200):
        if isinstance(a, int) and isinstance(b, int):
            print(a + b + c + d)
        else:
            print('type error')
    get_sum(1,2, d = 5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可变参数

    *args 接收单独的变量
    **kwargs

    *args

    考虑场景:如果想用一个函数求两个数、三个数…多个数的和
    可以使用可变参数,这样将传入的多个参数形成一个元组,传递给函数
    也可以什么都不传,相当于一个空的元组
    这种自动形成元组的行为成为装包

    def get_sum(*args):
        print(args)
    get_sum(1,2)     # (1, 2) 输出的是元组
    get_sum(1,2,3,4,5) # (1, 2, 3, 4, 5)
    get_sum() # ()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里是列表

    a,*b,c,d = 1,2,3,4,5,6
    print(a,b,c,d)
    # 1 [2, 3, 4] 5 6
    
    • 1
    • 2
    • 3

    如果有两个可变参数,报错

    *a,*b,c,d = 1,2,3,4,5,6  
    # SyntaxError: two starred expressions in assignment
    
    • 1
    • 2

    拆包

    a,b,c = (1,2,3)
    print(a,b,c)  # 1 2 3
    # 先拆包后装包
    *a,b,c = (1,2,3,5,6,7)
    print(a,b,c)  # [1, 2, 3, 5] 6 7
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在可变参数的函数中传入一个列表,可以看到输出的是只有一个元素的元组
    那么怎么才能使得传入的函数的时候是分开的几个数呢?
    可以在调用的时候进行拆包,即在调用的时候加*号

    def get_sum(*args):
        print(args)
    get_sum([1,2,3]) # ([1, 2, 3],)
    get_sum(*[1,2,3]) # (1, 2, 3)
    
    def get_sum(a, *args):
        print(a,args)
    get_sum(1,2)     # 1 (2,)
    get_sum(1,2,3,4,5) # 1 (2, 3, 4, 5)
    get_sum([1,2,3]) # [1, 2, 3] ()
    get_sum(*[1,2,3]) # 1 (2, 3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    **kwargs

    输出是一个字典,而传递给两个位置参数的话会报错,显示需要0个位置参数
    那么应该怎么传递呢?
    可以传递关键词参数,会转换为字典
    kw指的是key word
    必须传递关键字参数,会将其转换成key:value的形式,封装到字典里

    def show_book(**kwargs):
        print(kwargs)
    show_book() # {}
    show_book('a','b') # 报错:TypeError: show_book() takes 0 positional arguments but 2 were given
    show_book(name ='a') # {'name': 'a'}
    
    # 拆包传字典
    dict1 = {'name':'a', 'num': 2}
    show_book(**dict1) # {'name': 'a', 'num': 2}
    # 用一个*拆包,拆出来是两个key值
    print(*dict1) # name num
    # 直接输出**dict1会报错
    # print(**dict1) # TypeError: 'name' is an invalid keyword argument for print()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    两种一起用

    def show(*args, **kwargs):
        print(args)
        print(kwargs)
    show(1,2)  # (1, 2)/n  {}
    
    dict1 = {'name':'a', 'num': 2}
    show(1,2,**dict1)
    # (1, 2)
    # {'name': 'a', 'num': 2}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 args的后面, 但如果有*kwargs的话,kwargs必须是最后的

    def sum_nums_3(a, *args, b=22, c=33, **kwargs):
        print(a)
        print(b)
        print(c)
        print(args)
        print(kwargs)
    
    sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    一般情况下默认值参数会放在*args的后面

    # c在前面的话,传参的时候第三个参数会赋值给c
    def fun(a, b, c = 10, *args, **kwargs):
        print(a,b,c,args,kwargs)
    fun(1,2,3,4,5,name='a')
    # 1 2 3 (4, 5) {'name': 'a'}
    
    # c在可变参数后面,赋值的时候c需要用关键字参数赋值方法
    def fun(a, b, *args, c = 10, **kwargs):
        print(a,b,c,args,kwargs)
    fun(1,2,3,4,5,name='a')
    # 1 2 10 (3, 4, 5) {'name': 'a'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    kwargs必须在最后面
    在这里插入图片描述

    返回值

    python中函数可以返回多个返回值
    如果返回多个值,会将多个值封装到一个元组里返回

    def returning():
        return 1,2
    res = returning()
    a,b = returning() # 1,2
    print(res) # (1, 2)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    全局变量和局部变量

    当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值
    (这里和之前学其他语言好像不太一样,在java中的一个方法中可以直接对全局变量进行更改,而在python中不能对函数外的变量直接进行修改,只能做查看的操作;为什么呢,刚刚去写了一段java代码感受了一下,可以做一个不专业的直观的解释,因为java中对变量的声明是需要加变量类型的,所以如果在函数内声明了和全部变量一样的变量,那么在函数内使用的就是这个局部变量,简单来说就是修改变量和声明变量代码是不一样的;而在python中声明变量不需要加变量类型,同样如果在函数中声明了一个和全局变量一样的变量,那么这只能认为是一个声明变量的操作,而不能作为一个修改全局变量的操作,否则就会出现问题,所以在python中函数不能直接对全局变量进行修改)

    那么怎么才能在函数中修改全局变量呢?
    需要在函数中声明我用的就是全局变量

    a = 10
    def check():
        global a # 如果不加这句话会报错,因为不能直接对全局变量进行修改
        a -= 10
        print(a)
    check() # 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据 也理解为对全局变量进行修改,而不是定义局部变量
    如果在一个函数中需要对多个全局变量进行修改,那么可以一次性全部声明,也可以分开声明

    # 可以使用一次global对多个全局变量进行声明
    global a, b
    # 还可以用多次global声明都是可以的
    # global a
    # global b
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查看所有的全局变量和局部变量

    Python提供了两个内置函数globals()和locals()可以用来查看所有的全局变量和局部变量。

    def test():
        a = 100
        b = 40
        print(locals())  # {'a': 100, 'b': 40}
    
    test()
    
    x = 'good'
    y = True
    print(globals())  # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x101710630>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/jiangwei/Desktop/Test/test.py', '__cached__': None, 'test': <function test at 0x101695268>, 'x': 'good', 'y': True}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    可变数据类型和不可变数据类型

    所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
    可变类型(修改数据,内存地址不会发生变化)有: 列表、字典、集合
    不可变类型(修改数据,内存地址必定发生变化)有:int、float、bool、字符串、元组
    (python中有小整数对象池,字符串缓存池)
    只有不可变数据类型才需要加global

    函数中的注释

    在函数的第一行用一个字符串作为函数文档

    >>> def test(a,b):
    ...     "用来完成对2个数求和"  # 函数第一行写一个字符串作为函数文档
    ...     print("%d"%(a+b))
    ... 
    >>> 
    >>> test(11,22)  # 函数可以正常调用
    33
    >>>
    >>> help(test)  # 使用 help 查看test函数的文档说明
    Help on function test in module __main__:
    
    test(a, b)
        用来完成对2个数求和
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在函数内加一对三引号,会自动出现param…类似的,与java中的/** */相似

    def get_info(name: str, age: int):
        """
        接收用户的名字和年龄,拼接一个字符串并返回
    
        :param name: 接收一个名字
        :param age: 接收用户的年龄,必须是 0-200 间的一个整数
        :return: 返回拼接好的字符串
        """
        return "我的名字叫 %s,今年是 %d 岁" % (name, age)
    
    
    get_info("吴彦祖", 19)
    get_info(520, 19)  # 注意,形参上标注的类型只是提高代码的可读性,并不会限制实参的类型
    help(get_info)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    引用

    sys.getrefcount() 获取引用个数(本身调用这个方法也有一个引用指向目标地址),例如下面的例子 3 + 1 = 4

    import sys
    list1 = [1,2,3,4]
    list2 = list1
    list3 = list1
    print(sys.getrefcount(list1)) # 4
    
    # del list3
    # print(sys.getrefcount(list1)) # 3
    
    del list1 
    print(sys.getrefcount(list2)) # 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    嵌套函数

    函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了。函数还可以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包问题。

    函数嵌套
    函数也是一个变量,所以函数内部也可以定义函数,相当于声明了一个变量

    如果要修改外部函数的变量,需要在内部函数中声明对外部变量的使用,即加关键字nonlocal

    def outer():
        a = 10
        print('outer----hello')
        def inner():  # inner这个函数是在outer函数内部定义的
            b = 20
            nonlocal a # nonlocal表示引用内部函数外侧的局部变量a
            a += b
            print('inner----hello')
        inner()  # inner函数只在outer函数内部可见
        print(inner)   # <function outer.<locals>.inner at 0x00000134E031AEA0>
        # 用来查看局部变量
        print(locals())  # {'a': 10, 'inner': <function outer.<locals>.inner at 0x00000223594EAEA0>}
    
    outer()
    # inner()  这里会报错,在outer函数外部无法访问到inner函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    闭包

    符合以下三个条件是闭包:

    是一个嵌套函数
    内部函数引用了外部函数的变量
    返回值是内部函数

    闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数块+引用环境)。

    下面这段代码前两个调用中,因为内部函数返回的是函数名,我们知道,相当于一个变量,打印出来是它的地址
    而在后两个调用中,因为outer(x)返回的是一个函数名,用函数名调用内部函数,所以返回的是内部函数的返回值,相当于res = outer(x), t = res()

    因为无法直接在外部调用内部的inner()函数,所以这里在外部函数中将inner()当做返回值返回,就可以在外部使用这个内部函数

    def outer(n):
        num = n
        def inner():
            return num+1
        return inner
    
    print(outer(3))  # <function outer.<locals>.inner at 0x0000020E2905AEA0>
    print(outer(5))  # <function outer.<locals>.inner at 0x0000020E2905AEA0>
    
    print(outer(3)()) # 4
    print(outer(5)()) # 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这段程序中,函数 inner 是函数 outer 的内嵌函数,并且 inner 函数是outer函数的返回值。我们注意到一个问题:内嵌函数 inner 中引用到外层函数中的局部变量num,Python解释器会这么处理这个问题呢? 先让我们来看看这段代码的运行结果,当我们调用分别由不同的参数调用 outer 函数得到的函数时,得到的结果是隔离的(相互不影响),也就是说每次调用outer函数后都将生成并保存一个新的局部变量num,这里outer函数返回的就是闭包。 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

    闭包一般在装饰器中使用

    装饰器

    首先明白,函数名也是一个变量
    如下面代码中,将函数名b赋值给a,a变量指向了b函数的地址,因此运行结果是b

    def a():
        print('a')
    
    
    def b():
        print('b')
    
    a = b
    a() # b
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    为了在不修改原来已有函数的基础上,为函数添加新的功能(遵循开放封闭原则),出现了装饰器

    为了给房子刷墙,写了一个匿名函数,直接执行发现,貌似没有调用任何函数,但是出现了12的结果,说明@decorator 执行了装饰器函数,装饰器函数的参数是house,即将house函数作为参数传入装饰器中,因此会打印那两行横线,然后return 返回了wapper,house接收这个返回值,house = wrapper
    此时,house函数经过了装饰,已经变成了新的函数wrapper,这时候执行house会输出wrapper函数的执行结果

    def decorator(func):
        print('--------------1')
        print(func)
        def wrapper():
            print('---------')
            func()
            print('刷墙')
    
        print('--------------2')
        return wrapper
    
    # house = decorator(house)
    @decorator
    def house():
        print('毛坯房')
    
    # 输出
    # --------------1
    # <function house at 0x000002112911AEA0>  (这句话可以看出在执行之前,会进行装饰,将house函数传入装饰器中)
    # --------------2
    
    # 装饰后的house变成了wrapper
    print(house)  # <function decorator.<locals>.wrapper at 0x000002112911C1E0>  
    house()
    # 输出
    # ---------
    # 毛坯房
    # 刷墙
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    装饰器的功能

    • 引入日志
    • 函数执行时间统计
    • 执行函数前预备处理
    • 执行函数后清理功能
    • 权限校验等场景
    • 缓存

    带有参数的装饰器

    如果原函数有参数,则装饰器内部函数也需要有参数

    def check_time(action):
        def do_action(a,b):
            action(a,b)
        return do_action
    
    @check_time
    def go_to_bed(a,b):
         print('{}去{}睡觉'.format(a,b))
    
    go_to_bed("zhangsan","床上")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    不定长参数

    def test(cal):
        def do_cal(*args,**kwargs):
        		# 此时传入内部函数的是一个元组,需要拆包
            cal(*args,**kwargs)
        return do_cal
    
    # 体会多个参数的传递,需要*args
    @test
    def demo(a, b):
        sum = a + b
        print(sum)
    
    # 体会关键字参数的传递,需要**kwargs
    @test
    def demo2(a, b, c = 4):
    	sum = a + b + c
    	print(sum)
    	
    demo(1, 2)
    demo2(1, b = 2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    所以一般情况下,装饰器中的参数都会写成这两个可变参数

    装饰器修饰有返回值的函数

    一般情况下为了让装饰器更通用,可以有return

    def t_2(cal):
        def do_cal(*args,**kwargs):
            return cal(*args,**kwargs)  # 需要再这里写return语句,表示调用函数,获取函数的返回值并返回
        return do_cal
    
    @t_2
    def demo(a,b):
        return a + b
    
    print(demo(1, 2))  #3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    装饰器带参数

    了解

    执行顺序如下,先检测到outer_check(23),将参数23带入outer_check函数中,执行该函数,返回check_time
    然后执行check_time,将play_game传入函数中,返回do_action,此时play_game = check_time

    def outer_check(time):
        def check_time(action):
            def do_action():
                if time < 22:
                    return action()
                else:
                    return '对不起,您不具有该权限'
            return do_action
        return check_time
    
    @outer_check(23)
    def play_game():
        return '玩儿游戏'
    
    print(play_game())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    带有多个装饰器

    可见,先加载最靠近的装饰器,再加载较远的装饰器

    # 定义函数:完成包裹数据
    def makeBold(fn):
        print(1)
    
        def wrapped():
            return "<b>" + fn() + "</b>"
    
        print(2)
        return wrapped
    
    
    # 定义函数:完成包裹数据
    def makeItalic(fn):
        print(3)
    
        def wrapped():
            return "<i>" + fn() + "</i>"
    
        print(4)
        return wrapped
    
    
    def make(fn):
        print(5)
        def wrapped():
            return "<z>" + fn() + "</z>"
        print(6)
        return wrapped
    
    @make
    @makeBold
    @makeItalic
    def t_3():
        return "hello world-3"
    
    
    print(t_3())
    # 输出:3 4 1 2 5 6
    # <z><b><i>hello world-3</i></b></z>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    匿名函数

    一般不用

    用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。

    lambda函数的语法只包含一个语句,如下:
    lambda 参数列表: 返回值表达式

    sum = lambda arg1, arg2: arg1 + arg2
    
    # 调用sum函数
    print("Value of total : %d" % sum( 10, 20 ))
    print("Value of total : %d" % sum( 20, 20 ))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Lambda函数能接收任何数量的参数但只能返回一个表达式的值

    匿名函数可以执行任意表达式(甚至print函数),但是一般认为表达式应该有一个计算结果供返回使用。

    python在编写一些执行脚本的时候可以使用lambda,这样可以接受定义函数的过程,比如写一个简单的脚本管理服务器。

    应用场合:

    可以作为参数传递

    >>> def fun(a, b, opt):
    ...     print("a = " % a)
    ...     print("b = " % b)
    ...     print("result =" % opt(a, b))
    ...
    >>> add = lambda x,y:x+y
    >>> fun(1, 2, add)  # 把 add 作为实参传递
    a = 1
    b = 2
    result = 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Python中使用函数作为参数的内置函数和类:
    在这里插入图片描述

    系统高阶函数

    在Python中,函数其实也是一种数据类型。
    函数对应的数据类型是 function,可以把它当做是一种复杂的数据类型。
    既然同样都是一种数据类型,我们就可以把它当做数字或者字符串来处理。

    既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,同样,我们还可以把一个函数当做另一个函数的返回值。这种函数的使用方式我们称之为高阶函数。

    函数作为另一个函数的参数如上已经说过,作为返回值就如闭包中返回内部函数一样,将函数名作为返回值

    def test():
        print('我是test函数里输入的内容')
    
    def demo():
        print('我是demo里输入的内容')
        return test  # test 函数作为demo函数的返回值
    
    result = demo()  # 我是demo里输入的内容  调用 demo 函数,把demo函数的返回值赋值给 result
    print(type(result)) # <class 'function'>  result 的类型是一个函数
    
    result() # 我是demo里输入的内容    我是test函数里输入的内容   既然result是一个函数,那么就可以直接使用() 调用这个函数
    
    demo()()  # 我是demo里输入的内容    我是test函数里输入的内容
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    系统高阶函数:
    max,min,sorted
    如要对以下内容找出年龄最大的一项

    students = [
        {'name': 'zhangsan', 'age': 18, 'score': 92},
        {'name': 'lisi', 'age': 20, 'score': 90},
        {'name': 'wangwu', 'age': 19, 'score': 95},
        {'name': 'jerry', 'age': 21, 'score': 98},
        {'name': 'chris', 'age': 17, 'score': 100},
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    直接调用max不可行,max中的key关键字可以传入一个函数,表示排序的依据

    students = [
        {'name': 'zhangsan', 'age': 18, 'score': 92},
        {'name': 'lisi', 'age': 20, 'score': 90},
        {'name': 'wangwu', 'age': 19, 'score': 95},
        {'name': 'jerry', 'age': 21, 'score': 98},
        {'name': 'chris', 'age': 17, 'score': 100}
    ]
    print(max(students, key=lambda x: x['age']))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    filter() 过滤,filter里的匿名函数要求返回值必须是布尔类型
    选出年龄大于等于20的人

    res = filter(lambda x : x.get('age') >= 20, students)
    print(list(res))
    # [{'name': 'lisi', 'age': 20, 'score': 90}, {'name': 'jerry', 'age': 21, 'score': 98}]
    
    • 1
    • 2
    • 3

    map() 函数,通过匿名函数想提取的内容,并对内容进行加工,放在一个可迭代的对象里

    print(list(map(lambda x: x['score'] / 2, students)))
    # [46.0, 45.0, 47.5, 49.0, 50.0]
    
    • 1
    • 2

    reduce,在functools模块里,对序列进行压缩运算
    在这里插入图片描述

  • 相关阅读:
    Linux多线程概念及实现
    【Research】Wafer晶圆异常检测研究
    Linux系列之:9秒钟掌握多种实时查询日志的方法,再也不用cat命令了。
    大语言模型(一)OLMo
    数据结构与算法之一道题感受算法(算法入门)
    「Python条件结构」求三角形的面积
    filebrowser 文件系统搭建与使用
    iptables与firewalld防火墙
    我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:区分栈的指令集架构和寄存器的指令集架构
    MySQL——增删改查
  • 原文地址:https://blog.csdn.net/windyjcy/article/details/125479231