【问题标题】: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 不知道函数的名称

标签: python lambda


【解决方案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]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-16
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多