• Python学习笔记:匿名函数与lambda表达式


    一、Python函数

    Python 中使用 def + 函数名 + 参数 的方式定义函数,即:

    # 函数定义
    def function_name(parameters): # 形参
        print("hello" + parameters)
       
    # 函数调用
    function_name("Hider") # 实参
    

    将通过 def 所定义的函数称为“有名函数”。

    匿名函数则是没有明确的定义函数名。

    二、匿名函数

    lambda表达式:通常是在需要一个函数,但又不想去命名一个函数的时候使用,即匿名函数。

    匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数。

    匿名函数不需要显示地定义函数名,使用 lambda + 参数 + 表达式 的方式,即:

    lambda [arg1 [,arg2, ...argN]]: expression
    

    可以传入多个参数,但只能有一个表达式。

    # 实际对比案例
    # def定义方式
    def fun(x, y):
        return x*y
    
    # 调用
    fun(2, 3)
    6
    
    # 匿名函数
    func = lambda x,y : x*y
    func(2, 3)
    6
    
    # 定义def
    def calc(x,y):
        if x > y:
            return x*y
        else:
            return x/y
    # 执行
    calc(2,5) # 0.4
    calc(5,2) # 10
    
    # 三元运算换成匿名函数
    calc = lambda x, y : x*y if x > y else x/y
    calc(2,5) # 0.4
    calc(5,2) # 10
    

    匿名函数的优势:

    1. 不需要取名称
    2. 可以直接使用,不用提前定义,方便修改
    3. 语法结构简单

    三、应用

    1.应用在函数式编程中

    Python提供了很多函数式编程的特性。

    map、reduce、filter、sorted等函数都支持函数作为参数,lambda函数就可以应用在函数式编程中。

    • map函数

    map函数接收两个参数,一个是函数,一个是iterator(可迭代对象),map将传入的函数依次作用到序列的每个元素,并把结果作为新的iterator返回。

    # 返回n*n列表
    # 方法1
    list1 = [1,2,3,4,5,6,7,8,9,10]
    for i in range(len(list1)):
        list1[i] = list1[i]**2
    print(list1)
    # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    # 方法2
    list2 = [1,2,3,4,5,6,7,8,9,10]
    for i, val in enumerate(list2):
        list2[i] = val * val
    print(list2)
    # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    # 方法3:高级用法
    list3 = [1,2,3,4,5,6,7,8,9,10]
    print(list(map(lambda x:x**2, list3)))
    # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    # 针对列表转换为字典
    number_list = [100, 77, 69, 31, 44, 56]
    num_sum = list(map(lambda x:{str(x):x}, number_list))
    print(num_sum)
    
    • reduce函数

    reduce把一个函数作用在一个序列上,接收2个参数,reduce把结果继续和序列的下一个元素做累积计算。

    # 接收一个list并利用reduce()求积
    from functools import reduce
    list4 = [1,2,3,4,5,6,7,8,9,10]
    reduce(lambda x,y:x*y, list4) 
    # 1*2*3*4*5*6*7*8*9*10 = 3628800
    
    • filter函数

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

    # 删除偶数 只保留奇数
    list5 = [1,2,3,4,5,6,7,8,9,10]
    list(filter(lambda x:x%2==1, list5))
    # [1, 3, 5, 7, 9]
    
    # 取反操作
    x = 1563
    str(x)[::-1] # '3651'
    
    # 回数是指从左向右读和从右向左读都是一样的数,例如12321,909
    # 利用filter筛选出回数
    list6 = list(range(200))
    print(list(filter(lambda x:int(str(x)) == int(str(x)[::-1]), list6)))
    # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
    
    • sorted函数

    sorted函数使用格式:sorted(iterable, /, *, key=None, reverse=False)

    接收一个key函数实现对可迭代对象的自定义排序。

    可迭代对象:列表、字符串、元组、集合、字典。

    reverse为排序方向,默认从小到大,True为逆向。

    例如:

    # 将列表中的元素按照绝对值大小进行升序排列
    list1 = [3,5,-4,-1,0,-2,-6]
    sorted(list1, key=lambda x:abs(x))
    # [0, -1, -2, 3, -4, 5, -6]
    
    # def
    def get_abs(x):
        return abs(x)
    sorted(list1, key=get_abs)
    # [0, -1, -2, 3, -4, 5, -6]
    
    # 以首字母排序
    li = ['bad', 'about', 'Zoo', 'Credit']
    sorted(li, key=lambda x:x[0])
    # ['Credit', 'Zoo', 'about', 'bad']
    """
    对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。
    """
    
    # 学生姓名 + 成绩
    L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    # 按姓名排序
    sorted(L, key=lambda x:x[0])
    # [('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
    # 按成绩从高到低
    sorted(L, key=lambda x:x[1], reverse=True)
    # [('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
    
    # 针对字典操作
    member_list = [
        {"name": "风清扬", "age": 99, "power": 10000},
        {"name": "无崖子", "age": 89, "power": 9000},
        {"name": "王重阳", "age": 120, "power": 8000}
    ]
    new_list = sorted(member_list, key=lambda x:x["power"])
    print(new_list)
    

    2.应用在闭包中

    # 定义
    def get_y(a,b):
        return lambda x:a*x+b
    # 调用
    y1 = get_y(1,1)
    y1(1) # 2
    
    # def
    def get_y(a,b):
        def func(x):
            return a*x+b
        return func
    y1 = get_y(1,1)
    y1(1) # 2
    

    Python之禅中有这么一句话:Explicit is better than implicit(明了胜于晦涩),哪种方式更清晰就用哪一种方式,不要盲目的都使用lambda表达式。

    参考链接1:一文搞懂Python匿名函数

    参考链接2:Python函数学习——匿名函数

    参考链接3:Python匿名函数lambda的使用

  • 相关阅读:
    简直不敢相信...
    halcon 保存Region [原创]
    VS2015 下载链接
    C#【数据转换】十进制yte[]相互转换
    C# 复制窗体问题完美解决办法
    TextBox 保持固定长度,添加新行滚动到最后,跨线程。
    mysql isnull
    C#跨线程访问控件[我的记录]
    C# 常用类-IO-ClassExcelExport
    C# 常用类-IO-ClassXML
  • 原文地址:https://www.cnblogs.com/hider/p/14696046.html
Copyright © 2020-2023  润新知