zoukankan      html  css  js  c++  java
  • 「Lambda」Python中的匿名函数

    最近深入研究了一下Python里匿名函数的作用,所以来记录一下。

    你可能知道,从Java7到Java8发生了一个很大的变动,那就是增加了匿名函数。利用Java8中的匿名函数,你可以将函数直接赋值给一个变量。如果你需要实现一个只需要用到一次的接口,传统的Java7要求你必须定义一个“污染环境”的接口,而利用lambda,Java8就会干净许多。

    再回到Python上来。首先,Python中lambda的格式是这样的:

    lambda <参数>: <表达式>
    

    表达式就是函数体。

    参数和有名函数的规则是一样的,你同样可以通过a=1来赋默认值,也同样可以使用*args**kwargs

    Python中的lambda其实并没有像Java中那样大的影响,因为,Python中,一般的有名函数也可以实现闭包,赋值给变量这些功能。lambda只是让你能够将函数嵌入到一行内,这就让你在编写一些功能简单,并且一次性的函数时,代码会简洁许多。给一个例子:

    # 有名函数
    def square(x):
        return x**2
    
    
    squared = list(map(square, [1, 2, 3, 4, 5]))
    

    但如果我们使用lambda,就会简洁很多:

    # 匿名函数
    squared = list(map(lambda x: x**2, [1, 2, 3, 4, 5]))
    

    Python中的lambda也有很多限制,比如说函数体只能由一条表达式组成,这也就使得lambda不能实现一些复杂的功能。

    切记,不要为了将代码压缩到一行而使用过于复杂的lambda嵌套,这样会使你的代码无法阅读。Python注重可读性,The Zen of Python中强调:

    Flat is better than nested.

    你的确可以用lambda将一个较为复杂的程序写成一行,比如,这是一个仅用一行完成的猜数游戏,长这样:

    (lambda __builtin__: (lambda __print, __y, d: [(lambda ___: None)(d.guess_my_number(42)) for d.guess_my_number in [(lambda n:[(__y(lambda __this: (lambda d: (lambda __after: [(lambda __after: (lambda ___: __after(d))(__print('Not a positive integer!')) if (d.len(d.user_input)==0 or (not d.user_input.isdigit())) else [(lambda __after: (lambda ___: __after(d))(__print('Too big! Try again!')) if d.user_input>d.n else (lambda __after: (lambda ___: __after(d))(__print('Too small! Try again!')) if d.user_input<d.n else (lambda ___: d.True)(__print('You win!')))(lambda d: __after(d)))(lambda d: __after(d)) for d.user_input in [(d.int(d.user_input))]][0])(lambda d: __this(d)) for d.user_input in [(d.raw_input('Enter a positive integer to guess: '))]][0] if d.True else __after(d))(lambda d: None))))(d) for d.n in [(n)]][0])]][0])(__builtin__.__dict__['print'],(lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))
    
    

    我想这样你就会对嵌套后的lambda有多难阅读有个体会,这种代码看看玩就行。GitHub上面有一个库,可以帮助你将代码写到一行内

    lambda与Python内置函数结合使用

    lambda还可以与Python内置函数结合在一起使用,比如说我在举例说明lambda作用时使用的map()。

    map()

    Map会将一个函数映射到一个输入列表的所有元素上。换个说法,就是将列表中每个元素作为函数的输入值,然后将此元素更改为函数的输出值。

    此时,lambda用于指定对每个元素的共同操作。

    还是用开头的那个例子,使用map是这样写的:

    squared = list(map(lambda x: x**2, [1, 2, 3, 4, 5]))
    # result: [1, 4, 9, 16, 25]
    

    不使用map就得用for循环:

    items = [1, 2, 3, 4, 5]
    squared = []
    for i in items:
        squared.append(i**2)
    

    你看,map是不是简单漂亮的多。

    当然,这里注意一个点,在Python2中,map返回的是一个列表,而在Python3中,map返回的是迭代器,要想得到返回的列表,可以使用list,所以上面我也是这么做的。

    filter()

    顾名思义,filter就是过滤器。Filter会检查列表中的所有元素,并筛选出对前面函数能返回True的元素。

    此时,lambda用于指定筛选条件。

    举一个简单的例子:

    less_than_zero = list(filter(lambda x: x < 0, range(-10, 10)))
    # result: [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]
    

    同样要注意在Python3中返回值为迭代器的问题。

    reduce()

    Reduce用于将列表中相邻的两个元素依次结合在一起。

    此时,lambda用于指定元素的结合方式。

    同样,这里有一个例子:

    product = reduce(lambda x, y: x*y, range(10))
    # result: 3628800
    

    这里需要注意的点是,在Python2中,reduce是内置函数,而在Python3中,你需要用from functools import reduce导入才可使用。

    Ending

    在最后,我还有一点要说的是,关于lambda,有两个极为nb的东西:

    [lambda表达式(lambdaquad expression)quad和quadlambda算法(lambdaquad caculus) ]

    不过,对Python中的lambda而言,并不存在lambda expression和lambda caculus,所以,如果你看到别人在写关于Python lambda的文章时写到:

    我使用的原理就是lambda caculus。

    你大可无视掉。再次强调,Python中的lambda就是一个没有名字的、能够嵌入到一行内的函数

  • 相关阅读:
    hackrank Sorting Array of Strings
    c programming create a file
    spine unity3D(摘自博主softimagewht)
    实现鼠标双击(OnGUI)
    使用Unity NGUIInputField组件输入时发现显示为白色就是看不到字体
    NGUI制作可滚动的文本框(摘,如有侵权,联系删除)
    Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)
    MVC简单随笔
    Unity脚本自动添加注释脚本及排版格式
    树和树的分类
  • 原文地址:https://www.cnblogs.com/liuxizai/p/13765307.html
Copyright © 2011-2022 走看看