zoukankan      html  css  js  c++  java
  • Python lambda表达式

    Python lambda表达式(匿名函数)及用法

    lambda 表达式(又称匿名函数)是现代编程语言争相引入的一种语法,如果说函数是命名的、方便复用的代码块,那么 lambda 表达式则是功能更灵活的代码块,它可以在程序中被传递和调用。

    使用 lambda 表达式代替局部函数

    lambda 表达式的语法格式如下:

    lambda [parameter_list] : 表达式
    
    从上面的语法格式可以看出 lambda 表达式的几个要点:
    lambda 表达式必须使用 lambda 关键字定义。
    在 lambda 关键字之后、冒号左边的是参数列表,可以没有参数,也可以有多个参数。如果有多个参数,则需要用逗号隔开,冒号右边是该 lambda 表达式的返回值。
    [root@kube lambda]# cat demo.py 
    #coding:utf-8
    
    def get_fun(type):
        if type == 'square':
            return lambda n: n * n            # lambda 代替了函数的重新定义
        elif type == 'cube':
            return lambda n: n * n * n
        else:
            return lambda n: n + n
    
    a = get_fun('square')
    b = get_fun('type')
    
    print(a(5))
    print(b(5))
    
        
    [root@kube lambda]# py demo.py 
    25
    10
    [root@kube lambda]# 

    总体来说,函数比 lambda 表达式的适应性更强,lambda 表达式只能创建简单的函数对象(它只适合函数体为单行的情形)。但 lambda 表达式依然有如下两个用途:

    • 对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁。
    • 对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高了性能。
    [root@kube lambda]# cat demo1.py 
    #coding:utf-8
    
    x = map( lambda x: x*x ,range(8))
    print('x:',x)
    
    print([i for i in x])
    [root@kube lambda]# py demo1.py 
    x: <map object at 0x7f8d535a7890>
    [0, 1, 4, 9, 16, 25, 36, 49]
    [root@kube lambda]# 

     正如从上面代码所看到的,内置的 map() 函数的第一个参数需要传入函数,此处传入了函数的简化形式:lambda 表达式,这样程序更加简洁,而且性能更好。

     节所介绍的 lambda 表达式是 Python 编程的核心机制之一。Python 语言既支持面向过程编程,也支持面向对象编程。而 lambda 表达式是 Python 面向过程编程的语法基础,因此读者必须引起重视。

    Python eval()和exec()函数详解

    eval() 和 exec() 函数都属于 Python 的内置函数,由于这两个函数在功能和用法方面都有相似之处,所以将它们放到一节进行介绍。

    eval() 和 exec() 函数的功能是相似的,都可以执行一个字符串形式的 Python 代码(代码以字符串的形式提供),相当于一个 Python 的解释器。二者不同之处在于,eval() 执行完要返回结果,而 exec() 执行完不返回结果(文章后续会给出详细示例)。

    eval()和exec()的用法
    eval() 函数的语法格式为:
    eval(expression, globals=None, locals=None, /)
    
    
    而 exec() 函数的语法格式如下:
    exec(expression globals=None, locals=None, /)

    可以看到,二者的语法格式除了函数名,其他都相同,其中各个参数的具体含义如下:

    • expression:这个参数是一个字符串,代表要执行的语句 。该语句受后面两个字典类型参数 globals 和 locals 的限制,只有在 globals 字典和 locals 字典作用域内的函数和变量才能被执行。
    • globals:这个参数管控的是一个全局的命名空间,即 expression 可以使用全局命名空间中的函数。如果只是提供了 globals 参数,而没有提供自定义的 __builtins__,则系统会将当前环境中的 __builtins__ 复制到自己提供的 globals 中,然后才会进行计算;如果连 globals 这个参数都没有被提供,则使用 Python 的全局命名空间。
    • locals:这个参数管控的是一个局部的命名空间,和 globals 类似,当它和 globals 中有重复或冲突时,以 locals 的为准。如果 locals 没有被提供,则默认为 globals。

    注意,__builtins__ 是 Python 的内建模块,平时使用的 int、str、abs 都在这个模块中。通过 print(dic["__builtins__"]) 语句可以查看 __builtins__ 所对应的 value。

     实例:

    [root@kube lambda]# cat eval.py 
    x = 10
    def func():
      y = 20
      a = eval('x + y')
      print('a: ', a)
      b = eval('x + y', {'x': 1, 'y': 2})
      print('b: ', b)
      c = eval('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
      print('c: ', c)
      d = eval('print(x, y)')
      print('d: ', d)
    func()
    [root@kube lambda]# py eval.py 
    a:  30
    b:  3
    c:  4
    10 20
    d:  None
    [root@kube lambda]# 

    对输出结果的解释:

    对于变量a,eval函数的globals和locals参数都被忽略了,因此变量x和变量y都取得的是eval函数被调用环境下的作用域中的变量值,即:x = 10, y = 20,a = x + y = 30

    对于变量b,eval函数只提供了globals参数而忽略了locals参数,因此locals会取globals参数的值,即:x = 1, y = 2,b = x + y = 3

    对于变量c,eval函数的globals参数和locals都被提供了,那么eval函数会先从全部作用域globals中找到变量x, 从局部作用域locals中找到变量y,即:x = 1, y = 3, c = x + y = 4

    对于变量d,因为print()函数不是一个计算表达式,没有计算结果,因此返回值为None

    我们把实例1中的eval函数换成exec函数试试:

    [root@kube lambda]# cat eval.py 
    x = 10
    def func():
      y = 20
      a = exec('x + y')
      print('a: ', a)
      b = exec('x + y', {'x': 1, 'y': 2})
      print('b: ', b)
      c = exec('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
      print('c: ', c)
      d = exec('print(x, y)')
      print('d: ', d)
    func()
    [root@kube lambda]# py eval.py 
    a:  None
    b:  None
    c:  None
    10 20             #只是执行 print(x,y) 返回值还是 None
    d:  None
    [root@kube lambda]# 
    因为我们说过了,exec函数的返回值永远为None。

    Python函数式编程(map()、filter()和reduce())详解

    所谓函数式编程,是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出。不改变原始数据

    Python map()函数

    map() 函数的基本语法格式如下:
    map(function, iterable)
    
    其中,function 参数表示要传入一个函数,其可以是内置函数、自定义函数或者 lambda 匿名函数;iterable 表示一个或多个可迭代对象,可以是列表、字符串等。
    
    map() 函数的功能是对可迭代对象中的每个元素,都调用指定的函数,并返回一个 map 对象。
    注意,该函数返回的是一个 map 对象,不能直接输出,可以通过 for 循环或者 list() 函数来显示。
    [root@kube lambda]# cat demo4.py 
    #coding:utf-8
    
    lt = [1,2,3,'a','b']
    
    new_list = map(lambda x: x*2,lt)
    print(new_list)
    print(type(new_list))
    print(list(new_list))
    [root@kube lambda]# py demo4.py 
    <map object at 0x7f98bb95c2d0>
    <class 'map'>
    [2, 4, 6, 'aa', 'bb']
    [root@kube lambda]# 
    [root@kube lambda]# cat demo5.py 
    listDemo1 = [1, 2, 3, 4, 5]
    listDemo2 = [3, 4, 5, 6, 7]
    new_list = map(lambda x,y: x + y, listDemo1,listDemo2)
    print(list(new_list))
    [root@kube lambda]# py demo5.py 
    [4, 6, 8, 10, 12]
    [root@kube lambda]# 

    Python filter()函数

    filter()函数的基本语法格式如下:
    filter(function, iterable)
    
    此格式中,funcition 参数表示要传入一个函数,iterable 表示一个可迭代对象。
    
    filter() 函数的功能是对 iterable 中的每个元素,都使用 function 函数判断,并返回 True 或者 False,最后将返回 True 的元素组成一个新的可遍历的集合。
    [root@kube lambda]# cat demo6.py 
    #coding:utf-8
    
    lt = [1,2,3,4,5]
    
    new_lt = filter(lambda x: x % 2  == 0 , lt)
    print(type(new_lt))
    print(list(new_lt))
    [root@kube lambda]# py demo6.py 
    <class 'filter'>
    [2, 4]
    [root@kube lambda]# 

    Python reduce()函数

    reduce() 函数通常用来对一个集合做一些累积操作,其基本语法格式为:
    reduce(function, iterable)
    
    其中,function 规定必须是一个包含 2 个参数的函数;iterable 表示可迭代对象。
    
    注意,由于 reduce() 函数在 Python 3.x 中已经被移除,放入了 functools 模块,因此在使用该函数之前,需先导入 functools 模块。
    [root@kube lambda]# cat demo7.py 
    #coding:utf-8
    
    import functools
    lt = [1,2,3,4,5,6]
    
    product = functools.reduce(lambda x,y: x * y,lt)
    print(product)
    [root@kube lambda]# py demo7.py 
    720
    [root@kube lambda]# 

    Python 3函数注解:为函数提供类型提示信息

    数注解是 Python 3 最独特的功能之一,关于它的介绍,官方文档是这么说的,“函数注解是关于用户自定义函数使用类型的完全可选的元信息”。也就是说,官方将函数注解的用途归结为:为函数中的形参和返回值提供类型提示信息。

    [root@kube lambda]# cat demo8.py 
    #coding:utf-8
    
    def  square(num: '一个数字')->'返回这个数的平方':
        return num ** 2
    print(square(200))
    print(square.__annotations__)
    [root@kube lambda]# py demo8.py 
    40000
    {'num': '一个数字', 'return': '返回这个数的平方'}
    [root@kube lambda]# 

    如上所示,给函数中的参数做注解的方法是在形参后添加冒号“:”,后接需添加的注解(可以是类(如 str、int 等),也可以是字符串或者表示式);给返回值做注解的方法是将注解添加到 def 语句结尾的冒号和 -> 之间。

    [root@kube lambda]# cat demo10.py 
    #coding:utf-8
    
    def solve(arr,target):
        b = sorted(arr)
        for i in b:
            if i * i > target:
                return i
        return -1
    
    print(solve([61, 2, 7, 4, 5, 8], 70))
    print(solve([10, 2, 3, 7, 5, 6], 9))
    print(solve([10, 20, 3, 4, 5, 6], 0))
    print(solve([10, 8, 3, 4, 5, 6], 200))
    
    
    
    [root@kube lambda]# py demo10.py 
    61
    5
    3
    -1
    [root@kube lambda]# 
    首先,大家在编程过程中,一定要围绕一个中心思想:不写重复性的代码。因为,重复代码往往是可以通过使用条件、循环、构造函数和类(后续章节会做详细介绍)来解决的
    还要学会刻意地减少代码的迭代层数,尽可能让 Python 代码扁平化。
    另外,在使用函数时,函数的粒度应该尽可能细,不要让一个函数做太多的事情。往往一个复杂的函数,我们要尽可能地把它拆分成几个功能简单的函数,然后合并起来。
  • 相关阅读:
    poj3181(Dollar Dayz)
    poj3666(Making the Grade)
    poj2392(Space Elevator)
    hdu5288(OO’s Sequence)
    hdu5289(Assignment)
    快学scala
    Spark Checkpointing
    Spark Performance Tuning (性能调优)
    Spark Memory Tuning (内存调优)
    Sparkstreaming and Kafka
  • 原文地址:https://www.cnblogs.com/zy09/p/11643289.html
Copyright © 2011-2022 走看看