4.7. 使用 lambda 函数
Description: Python from novice to pro
Keywords: Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free

# 深入 Python :Dive Into Python 中文版 Python 从新手到专家 [Dip_5.4b_CPyUG_Release] | Find:

## 4.7. 使用 `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

| 这是一个 `lambda` 函数，完成同上面普通函数相同的事情。注意这里的简短的语法：在参数列表周围没有括号，而且忽略了 `return` 关键字 (隐含存在，因为整个函数只有一行)。而且，该函数没有函数名称，但是可以将它赋值给一个变量进行调用。
| 使用 `lambda` 函数时甚至不需要将它赋值给一个变量。这可能不是世上最有用的东西，它只是展示了 `lambda` 函数只是一个内联函数。

总的来说，`lambda` 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。`lambda` 函数不能包含命令，包含的表达式不能超过一个。不要试图向 `lambda` 函数中塞入太多的东西；如果你需要更复杂的东西，应该定义一个普通函数，然后想让它多长就多长。

`lambda` 函数是一种风格问题。不一定非要使用它们；任何能够使用它们的地方，都可以定义一个单独的普通函数来进行替换。我将它们用在需要封装特殊的、非重用代码上，避免令我的代码充斥着大量单行函数。

### 4.7.1. 真实世界中的 `lambda` 函数

`apihelper.py` 中的 `lambda` 函数：

        processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)

注意这里使用了 `and-or` 技巧的简单形式，它是没问题的，因为 `lambda` 函数在布尔环境中总是为真。(这并不意味这 `lambda` 函数不能返回假值。这个函数对象的布尔值为真；它的返回值可以是任何东西。)

还要注意的是使用了没有参数的 `split` 函数。你已经看到过它带一个或者两个参数的使用，但是不带参数它按空白进行分割。

### 例 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'

| 这是一个多行字符串，通过使用转义字符的定义代替了三重引号。`\n` 是一个回车，`\t` 是一个制表符。
| 不带参数的 `split` 按照空白进行分割。所以三个空格、一个回车和一个制表符都是一样的。
| 通过 `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` 来间接调用函数。
- Python Tutorial 演示了如何从一个 `lambda` 函数内部访问外部变量。(PEP 227 解释了在 Python 的未来版本中将如何变化。)
- The Whole Python FAQ 有关于令人模糊的使用 `lambda` 单行语句的例子。