lambda和常规函数之间的python有啥区别?

Posted

技术标签:

【中文标题】lambda和常规函数之间的python有啥区别?【英文标题】:what is the difference for python between lambda and regular function?lambda和常规函数之间的python有什么区别? 【发布时间】:2012-08-29 04:37:41 【问题描述】:

我很好奇 lambda 函数和常规函数(用 def 定义)之间的区别 - 在 python 级别。 (我知道程序员有什么区别以及何时使用它们。)

>>> def a():
    return 1

>>> b = lambda: 1
>>> a
<function a at 0x0000000004036F98>
>>> b
<function <lambda> at 0x0000000004031588>

我们可以看到 - python 知道 b 是一个 lambda 函数,a 是一个常规函数。这是为什么?它们to python有什么区别?

【问题讨论】:

Python 支持在运行时使用名为“lambda”的构造创建匿名函数(即未绑定名称的函数)。您可以在secnetix.de/olli/Python/lambda_functions.hawk 中查看。这意味着它没有给你函数的名称。 @SuryawanshiManoj 这个问题如何让你相信 OP 没有意识到这一点? @Marcin:正如 Simeon Visser 在回答中显示下面的示例,您可以理解 OP 不知道函数的名称 【参考方案1】:

它们是相同的类型,因此它们的处理方式相同:

>>> type(a)
<type 'function'>
>>> type(b)
<type 'function'>

Python 还知道 b 被定义为 lambda 函数,并将其设置为函数名称:

>>> a.func_name
'a'
>>> b.func_name
'<lambda>'

换句话说,它会影响函数的名称,但就 Python 而言,两者都是函数,这意味着它们大部分可以以相同的方式使用。请参阅下面 mgilson 的评论,了解函数和 lambda 函数在酸洗方面的重要区别。

【讨论】:

lambda 函数不能被腌制,因为它们没有关联的(唯一)名称。 (因此,例如,它们不能与 multiprocessing 一起使用——这让我不止一次使用 PicklingError @mgilson:谢谢,很高兴知道。我已经更新了我的答案。 另外,值得指出的是lambda 是一个表达式,而def 是一个语句。由于lambda 是一个表达式,它只能包含其他表达式(不允许使用任何语句)——尽管这在程序员层面上更像是一个问题,而不是“为什么 python 会跟踪差异” lambdas 也可以用作表达式,而传统函数不能;但我想你已经知道了。 考虑到内部ab 属于同一类型,即两者都是functions,我假设一个没有性能优势?【参考方案2】:

唯一的区别是 (a) lambda 的主体只能包含一个表达式,其结果从创建的函数返回,并且 (b) lambda 表达式是一个表达式,其计算结果为函数对象,而def 语句没有值,并创建一个函数对象并将其绑定到一个名称。

在所有其他材料方面,它们产生相同的对象 - 适用相同的范围和捕获规则。 (无关紧要的区别是 lambda-created 函数的默认 func_name"&lt;lambda&gt;"。这可能会影响在深奥的情况下的操作 - 例如尝试腌制函数。

【讨论】:

【参考方案3】:

首先考虑两者的差异。

Lambda 函数: are 运算符可以有任意数量的参数,但它只能有一个表达式。它不能包含任何语句,它返回一个可以分配给任何变量的函数对象。它们可以在创建的块中使用。

def 函数: 函数有助于将我们的程序分解成更小的模块化块。随着我们的程序变得越来越大,功能使其更有条理和更易于管理。可以在任何我们想要的地方调用和使用它们。

这里你可以通过下面的例子得到更清楚的区别。

定义函数

    def add(a,b):
      return a+b
    print(add(4,5))

定义一个 lambda

    add = lambda x, y : x + y 
    print(add(4,5))

【讨论】:

感谢@Saurabh,但我的问题是 python 有什么区别,而不是如何使用它。【参考方案4】:

lambdadef 都创建了相同类型的函数——它们具有相同类型的元数据和功能。它们的技术区别在于句法

lambda 是一个产生函数的表达式def 是一个产生函数的语句

这就是决定它们如何使用的一切。其他明显差异仅来自lambda/def 可以捕获的信息。

>>> def def_func(): pass
>>> lambda_func = lambda: None
>>> type(def_func) == type(lambda_func)
True

用法:表达式与语句

lambda 更灵活,因为表达式可以是更多语言结构的一部分。

#                v--------------v arguments must be expressions
sort(values, key=lambda x: abs(x))

相比之下,def 更强大,因为它可以更多语言结构组成。

def encode(num, base):
    while num:   # statements must be inside statements
        num, bit = divmod(num, base)
        yield bit

这些差异直接源于一个是表达式,另一个是语句。 Python 没有特殊的规则来决定 lambda/def 可以在哪里使用。


野生&lt;lambda&gt;s 生长的地方

假设lambdadef 对应于不同类型的函数的主要原因是元数据lambda 通常被称为“匿名函数”,而且奇迹般地它总是产生一个function &lt;lambda&gt;。其他怪癖包括“无法腌制 lambda 函数”,最近键入 lambda 也“不起作用”。

这是因为与def 语法相比,lambda 语法无法指定名称、类型注释等。因此,Python 只是简单地为任何一个填充 defaults:名称变为 &lt;lambda&gt;,注释为空。

>>> identity = lambda a: a
>>> identity.__qualname__
'<lambda>'
>>> identity.__annotations__

由于&lt;lambda&gt; 不是一个有效的标识符,所有使用此元数据来查找函数的东西(最突出的是pickle)都会失败。

但是,这不会使函数成为“匿名函数”类型。可以修补元数据以插入 def 将提供的内容:

>>> identity.__qualname__ = identity.__name__ = 'identity'
>>> identity
<function __main__.identity(a)>

当然,在那一点上,你可以使用def...

【讨论】:

【参考方案5】:

Lambda 是一个内联函数,我们可以在其中执行任何没有函数名称的功能。 当我们将它用作高阶函数的参数时,它会很有帮助。 例如:一个将其他函数作为参数的函数。

函数定义示例:

>>> def func(a, b):
    return a * b

>>> func(2,3)
6
>>> type(func)
<class 'function'>
>>> func
<function func at 0x034B6E88>

Lambda 表达式示例:

>>> multiply = lambda a, b: a * b
>>> multiply(2, 3)
6
>>> type(multiply)
<class 'function'>
>>> multiply
<function <lambda> at 0x034B6ED0>

两者都返回相同的输出值。只有返回的对象不同。 Function 和 Lambda 的“func”名称。

【讨论】:

感谢您的回答,但请注意,我知道程序员有什么区别以及何时使用每个人(正如我在问题中所说)。【参考方案6】:

lambda 创建一个匿名函数。这个想法取自函数式编程语言。通过这种方式,您可以创建函数并将其传递给其他函数,例如 mapfilter。 (看here) 您也可以将普通函数传递给这些函数,但由于它们大多很简单,并且不会在其他任何地方使用,因此定义新函数的整个过程很不方便。

作为一个例子,看看这个:

>>> a = [1, 2, 3, 4]
>>> print map( lambda x : x*2 + 1, a )
[3, 5, 7, 9, 11]

【讨论】:

以上是关于lambda和常规函数之间的python有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

AWS lambda 和 AWS Lambda@EDGE 有啥区别?

AWS - 在 SNS 订阅或 Lambda 函数上设置死信队列有啥区别?

使用 boost::this_thread::sleep_for() 和常规 sleep() 函数有啥区别?

用于计算百分位数的纯 python 实现:这里的 lambda 函数有啥用?

多方法和多调度之间有啥区别吗?

java7和java8有啥区别