💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 4.7. 使用 `lambda` 函数 * 4.7.1\. 真实世界中的 lambda 函数 Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 `lambda` 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。 ## 例 4.20. `lambda` 函数介绍 ``` >>> def f(x): ... return x*2 ... >>> f(3) 6 >>> g = lambda x: x*2 >>> g(3) 6 >>> (lambda x: x*2)(3) 6 ``` | | | | --- | --- | | \[1\] | 这是一个 `lambda` 函数,完成同上面普通函数相同的事情。注意这里的简短的语法:在参数列表周围没有括号,而且忽略了 `return` 关键字 (隐含存在,因为整个函数只有一行)。而且,该函数没有函数名称,但是可以将它赋值给一个变量进行调用。 | | \[2\] | 使用 `lambda` 函数时甚至不需要将它赋值给一个变量。这可能不是世上最有用的东西,它只是展示了 `lambda` 函数只是一个内联函数。 | 总的来说,`lambda` 函数可以接收任意多个参数 (包括[可选参数](optional_arguments.html "4.2. 使用可选参数和命名参数")) 并且返回单个表达式的值。`lambda` 函数不能包含命令,包含的表达式不能超过一个。不要试图向 `lambda` 函数中塞入太多的东西;如果你需要更复杂的东西,应该定义一个普通函数,然后想让它多长就多长。 > 注意 > `lambda` 函数是一种风格问题。不一定非要使用它们;任何能够使用它们的地方,都可以定义一个单独的普通函数来进行替换。我将它们用在需要封装特殊的、非重用代码上,避免令我的代码充斥着大量单行函数。 ## 4.7.1. 真实世界中的 `lambda` 函数 `apihelper.py` 中的 `lambda` 函数: ``` processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) ``` 注意这里使用了 [`and-or`](and_or.html "4.6. and 和 or 的特殊性质") 技巧的简单形式,它是没问题的,因为 `lambda` 函数[在布尔环境中](../native_data_types/lists.html#tip.boolean)总是为真。(这并不意味这 `lambda` 函数不能返回假值。这个函数对象的布尔值为真;它的返回值可以是任何东西。) 还要注意的是使用了没有参数的 `split` 函数。你已经看到过它带[一个或者两个参数](../native_data_types/joining_lists.html#odbchelper.split.example "例 3.28. 分割字符串")的使用,但是不带参数它按空白进行分割。 ## 例 4.21. `split` 不带参数 ``` >>> s = "this is\na\ttest" >>> print s this is a test >>> print s.split() ['this', 'is', 'a', 'test'] >>> print " ".join(s.split()) 'this is a test' ``` | | | | --- | --- | | \[1\] | 这是一个多行字符串,通过使用转义字符的定义代替了[三重引号](../getting_to_know_python/documenting_functions.html#odbchelper.triplequotes "例 2.2. 定义 buildConnectionString 函数的 doc string")。`\n` 是一个回车,`\t` 是一个制表符。 | | \[2\] | 不带参数的 `split` 按照空白进行分割。所以三个空格、一个回车和一个制表符都是一样的。 | | \[3\] | 通过 `split` 分割字符串你可以将空格统一化;然后再以单个空格作为分隔符用 `join` 将其重新连接起来。这也就是 `info` 函数将多行 `doc string` 合并成单行所做的事情。 | 那么 `info` 函数到底用这些 `lambda` 函数、`split` 函数和 `and-or` 技巧做了些什么呢? ``` processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) ``` `processFunc` 现在是一个函数,但是它到底是哪一个函数还要取决于 `collapse` 变量。如果 `collapse` 为真,``processFunc`(_string_)` 将压缩空白;否则 ``processFunc`(_string_)` 将返回未改变的参数。 在一个不很健壮的语言中实现它,像 Visual Basic,你很有可能要创建一个函数,接受一个字符串参数和一个 _`collapse`_ 参数,并使用 `if` 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在 Python 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的 `lambda` 函数提供确切的 (唯一的) 你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 (哦,想到那些参数就头昏) 的错误。 ## `lambda` 函数进一步阅读 * Python Knowledge Base 讨论了使用 `lambda` 来[间接调用函数](http://www.faqts.com/knowledge-base/view.phtml/aid/6081/fid/241)。 * _Python Tutorial_ 演示了如何[从一个 `lambda` 函数内部访问外部变量](http://www.python.org/doc/current/tut/node6.html#SECTION006740000000000000000)。([PEP 227](http://python.sourceforge.net/peps/pep-0227.html) 解释了在 Python 的未来版本中将如何变化。) * _The Whole Python FAQ_ 有关于[令人模糊的使用 `lambda` 单行语句](http://www.python.org/cgi-bin/faqw.py?query=4.15&querytype=simple&casefold=yes&req=search)的例子。