从入门到入狱-------高阶函数和装饰器

入门 N day

  • max/min

    max的普通用法:

    max(序列)—求序列中的最大元素,但是序列中的类型必须一致,元素本身必须支持比较运算

    max的实参高阶用法:

    max(序列,key=函数)—通过函数来定制求最大值的方式

    序列—需要获取某种最大值对应的序列

    函数—有且只有一个参数(代表序列中每个元素),有一个返回值(求最大值的时候的比较对象)

    # 普通用法
    nums=[15,30,51,69,90]
    print(max(nums)
    # 高阶用法 :求个位数最大的元素
    max_nums=max(nums, key = lambda item:item % 10)
    print(max_nums)
    
    # 练习:求各位数之和的最大的元素
    nums=[930456671222]
    # 方法一
    def sum1(item):
          s=0
          for i in str(item):
          	s+=int(i)
          return s
    result=max(nums,key=sum1)
    print(result)
    # 方法二
    result=max(nums,key=lambda item:sum([int(i) for i in str(item)]))
    print(result)      
    # 练习 :已知以下列表    
    students = [
        {
          
          'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'},
        {
          
          'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'},
        {
          
          'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'},
        {
          
          'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'},
        {
          
          'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'},
        {
          
          'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'},
        {
          
          'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'}
    ]
          
    # 求列表中年龄最大的学生信息
    result=max(students,key=lambda i:i['age'])
    print(result)     
    # 求列表中成绩最低的学生信息
    result=min(students,key=lambda i:i['score'])     print(result) 
          
    # 求女生中年龄最大的学生信息
    new_students = [i for i in students if i['sex']=='女']
    result = max(new_students,key=lambda j:j['age'])
    print(result)
    '''
    解析:
    new_students = [i for i in students if i['sex']=='女']
    运用列表推导式得到一个含有所有女生信息的新列表
    result = max(new_students,key=lambda j:j['age'])
    再用max的高阶用法求出新列表中的最大值
    max的实参高阶用法:
    max(序列,key=函数)--- 通过函数来定制求最大值的方式 
    '''      
    # 求男生中年龄最小的学生信息
    result = min([i for i in students if i['sex']=='男'])     
    print(result)
                
    
  • sorted(序列)

    将序列中的元素按照元素的大小从小到大排序

    高阶用法:

    sorted(序列,key=函数)

    扫描二维码关注公众号,回复: 11995218 查看本文章

    函数:有且只有一个参数,指向序列中的每一个元素,有一个返回值,通过比较返回值的大小进行排序,返回值就是排序的标准

    # 按照序列元素大小排序
    nums = [1, 2454, 135, 456, 12, 0]
    result = sorted(nums[:],key=lambda item:item)
    print(result) #[0, 1, 12, 135, 456, 2454] 
    # 按照序列元素的个位数大小进行排序
    result = sorted(nums[:], key=lambda item: item % 10)
    print(result)  # [0, 1, 12, 2454, 135, 456]
    
    
    

    练习:按照数值大小排序

    datas = [23, '78', 56, '34', '102', 79]
    result = sorted(datas,key=lambda item:int(item))
    print(result) # [23, '34', 56, '78', 79, '102']
    # 全部变为int类型排序
    list1 = sorted([int(i) for i in datas])
    print(list1)  # [23, 34, 56, 78, 79, 102]
    
    

    将学生分数值从小到大排序

    students = [
        {
          
          'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'},
        {
          
          'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'},
        {
          
          'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'},
        {
          
          'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'},
        {
          
          'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'},
        {
          
          'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'},
        {
          
          'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'}
    ]
    
    lists = sorted([i['score'] for i in students if i['score']])
    print(lists)  # [54, 56, 67, 77, 78, 82, 100]
    
  • map

    用法一:

    map(函数,序列)—通过原序列中的元素进行指定的变换后产生新的序列

    函数—有且只有一个参数,参数指向后面序列中的元素,有一个返回值成为新序列中的元素

    # 产生一个新的列表,列表中是nums中元素的平方
    nums=[1,2,3,4]
    result = list(map(lambda i:i**2,nums))
    print(result) # [1,4,9,16]
    
    

    用法二:

    map(函数,序列1,序列2)—产生一个新的序列

    新序列的元素是序列1和序列2中元素通过指定变化产生的

    函数—有且只有两个参数(两个参数分别指向序列1和序列2中的元素),有一个返回值(新序列中的元素)

    map(函数,序列1,序列2,序列3,…)用法和序列二一样

    # 产生一个新的列表,列表中的元素是seq1加上seq2中元素的和
    seq1 = (1, 2, 3, 4)
    seq2 = [5, 6, 7, 8]
    result=list(map(lambda i, j:i + j, seq1, seq2))
    printI(result)   # [6, 8, 10, 12]
    
    
    

    练习:将tels中所有的电话号码,添加到students中的每个字典中,产生一个新的字典

    students = [
        {
          
          'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'},
        {
          
          'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'},
        {
          
          'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'},
        {
          
          'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'},
        {
          
          'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'},
        {
          
          'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'},
        {
          
          'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'}
    ]
    tels = ['110', '120', '114', '119', '12306', '10086', '10000']
    
    # 方法一
    def add_s():
        for j in range(len(tels)):
            students[j].setdefault('tels', tels[j])
            return students
    
    
    new_s = add_s()
    print(new_s)
    
    # 方法二
    def add_key(i, j):
        i['tel'] = j
        return i
    
    
    result = list(map(add_key, students, tels))
    print(result)
    
    
  • eval(序列)—将满足规范格式的序列的字符串转换成序列

    strs1='1,2,3,4,5,6'
    strs2='[1,2,3,4,5,6]'
    strs3='{1,2,3,4,5}'
    tuples=eval(strs1)
    lists=eval(strs2)
    gathers=eval(strs3)
    print(tuples,lists,gathers) 
    # (1, 2, 3, 4, 5, 6) [1, 2, 3, 4, 5, 6] {1, 2, 3, 4, 5}
    
  • reduce

    使用之前需要在最开头用functools模块导入

    from functools import reduce
    

    用法一:

    reduce(函数,序列)—将序列中的元素通过指定的规则合并成一个数据

    函数----有且只有两个参数,第一个参数第一次调用的时候指向序列中的第一个元素,从第二次开始,都是指向的上次运算的结果,第二个参数指向除了第一个参数的所有元素

    返回值----每次合并的结果(用来定制合并规则的)

    # 求序列所有元素的和
    
    nums = [10, 11, 12, 13, 14]
    def func1(x,y):
        print(f"x:{x},y:{y}") # 查看x,y的值看它们的变化
        return x+y
    result = reduce(func1, nums)
    print(result)
    '''
    
    第一次  x=10,y=11  x=x+y=21
    第二次  x=21,y=12  x=33
    ...
    ...
    最后一次 x=46,y=14 x=x+y
    '''
    

    用法二:

    reduce(函数,序列,初始值)

    函数:

    第一个参数:第一次指向初始值,从第二次开始参数指向上次合并的结果

    第二个参数:指向除了第一个元素的所有元素

    nums = [10, 11, 12, 13, 14]
    def func2(x, y):
        print(f"x:{x},y:{y}")
        return x+y
    result2 = reduce(func2, nums, 0)
    print(result2)
    
    # 练习:求个位数的和
    list1=[29, 38, 90, 34, 67]
    # 匿名函数
    results = reduce(lambda x, y:y%10+x, list1, 0)
    print(results)
    #普通函数
    def sums(x,y):
        y = y%10
        return x+y
    
    results = reduce(sums, list1, 0)
    print(results)
    
    # 拼接元素的个位数形成新的字符串
    list1 = [29, 38, 90, 34, 67]
    results = reduce(lambda x, y:x+str(y%10),list1,'')
    print(results)  #'98047'
    
    # 求所有学生的总分数
    students = [
        {
          
          'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'},
        {
          
          'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'},
        {
          
          'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'},
        {
          
          'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'},
        {
          
          'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'},
        {
          
          'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'},
        {
          
          'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'}
    ]
    
    results = reduce(lambda x, y: y['score'] + x, students, 0)
    print(results)
    
  • 装饰器

    装饰器是一种专门用来给其他函数添加功能的函数

    import time
    from functools import reduce
    # 导入时间模块
    # 给函数添加统计执行时间的功能
    # 方式一 直接在需要添加功能的函数中添加新功能的代码(缺点:同样功能的代码可能需要写多遍)
    # 原代码
    def func1():
        print('hello world')
    
    
    # 添加过后
    def func2():
        t1 = time.time()
        print('hello world')
        t2 = time.time()
        print('执行使用时间:', t2 - t1)
    
    
    func2()
    
    
    # 方式二 定义一个实参高阶函数来给指定函数添加功能(缺点:主次颠倒)
    def count_time(func, *args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print('执行时间:', end - start)
    
    
    def func3():
        time.sleep(0.1)
        print(1 * 2 * 3)
    
    
    count_time(func3)
    
  • 方法三:装饰器

    无参装饰器:

    装饰器=实参高阶函数+返回值高阶函数+糖语法

    def 函数名1(参数1):

    ​ def 函数名2(*args,**kwargs):

    ​ result=参数1(*args,**kwargs)

    ​ 实现添加功能的代码段

    ​ return result

    ​ return 函数名2

    说明:

    函数名1—装饰器的名字(按照当前装饰器添加的功能命名)

    参数1—用来接收被添加功能的函数(指向需要添加功能的函数),一般直接命名为func

    函数名2—表示的是在原函数的基础上添加完功能的新函数,一般直接命名为一个固定的名字:new_func

    使用装饰器:在需要添加功能的函数定义前加 @函数名1(糖语法)

    # 在原函数结束后打印‘====函数结束’
    def end1(func):
        def new_func(*args, **kwargs):
            result = func(*args, **kwargs)
            print('====函数结束')
            return result
        return new_func
    @end1
    def func5(x,y):
        print(x+y)
    func5(1,2)
    
    
    def func6(num):
        result = reduce(lambda x, y: x * y, range(1, num + 1))
        return result
    
    
    re = func6(4)
    print(re)
    
    
    # 例2:写一个装饰器,如果原函数是整数,就返回这个数的二进制表达方式
    def binary(func):
        def new_func(*args, **kwargs):
            result = func(*args, **kwargs)
            if type(result) != int:
                return result
            return bin(result)
    
        return new_func
    
    
    @binary
    def func11(x, y):
        return x + y
    
    
    print(func11(11, 22))
    print(0b100001)   # 33
    
    

猜你喜欢

转载自blog.csdn.net/weixin_44628421/article/details/109059217
今日推荐