<< >>

diveintopython.org |

Python for experienced programmers

## 2.7. `and-or` 技巧

如果你是一名C语言高手，当然对 `bool ? `a` : `b`` 表达式熟悉，这个表达式当 `bool` 为真时计算为 `a`，其它值则为 `b`。象很多编程技巧一样，它是一种诱人的便利。你可在Python中完成同样的事情，但是需要完全理解它是如何工作的，以避免不明显的毛病。

例 2.17. `and-or` 技巧

    >>> a = "first"
    >>> b = "second"
    >>> 1 and a or b
    'first'
    >>> 0 and a or b
    'second'

| 这个语法看起来与C语言中的 `bool ? `a` : `b`` 相似。第一部分将在布尔环境中进行计算，它可以是任意Python表达式。如果计算为真，整个表达式的值为 `a`。
| 如果第一部分计算为假，整个表达示的值为 `b`。

然而，因为这个Python表达式是简单的布尔逻辑，而不是一个特殊的语言结构，所以在这个Python的 `and-or` 技巧与C中的 `bool ? `a` : `b`` 语法之间，有一个非常，非常，非常重要的不同。如果 `a` 的值为假，表达式将不会按你期望的那样执行。(你能知道我被这个问题折腾过吗？不只一次？)

例 2.18. 何时 `and-or` 技巧失败

    >>> a = ""
    >>> b = "second"
    >>> 1 and a or b
    'second'

因为 `a` 是一个空串，空串在一个布尔环境中被Python看成假值，这个表达式将“失败”，且返回 `b` 的值。如果你不将它想象成象 `bool ? `a` : `b`` 一样的语法，而把它看成纯粹的布尔逻辑，这样的话就会得到正确的理解。 `1` 是真，`a` 是假，所以 ``1` and `a`` 是假。假 or `b` 是`b`。

这个 `and-or` 技巧，`bool and `a` or `b``，当 `a` 为假时，不会象C表达式 `bool ? `a` : `b`` 一样工作。

The real trick behind the `and-or` trick, then, is to make sure that the value of `a` is never false. One common way of doing this is to turn `a` into `[`a`]` and `b` into `[`b`]`, then taking the first element of the returned list, which will be either `a` or `b`.

Example 2.19. Using the `and-or` trick safely

    >>> a = ""
    >>> b = "second"
    >>> (1 and [a] or [b])[0]
    ''

因为 `[`a`]` 是一个非空列表，它永远不会为假。甚至 `a` 是 `0` 或 `''` 或其它假值，列表 `[`a`]` 为真，因为它有一个元素。

到现在为止，这个技巧可能看上去问题超过了它的价值。毕竟你可以用一个 `if` 语句完成相同的事情，那么为什么要经受这些麻烦呢？哦，在很多情况下，要在两个常量之间进行选择，所以可以使用更简单的语法而不必担心，因为你知道 `a` 值将总是真。并且尽管你不得不使用更复杂的安全形式，也有一些好的理由来使用这个技巧；在Python中有很多时候， `if` 语句不允许使用，这一点我们将在下一节看到。

一个负责的程序员应该将 `and-or` 技巧封装成一个函数：
    def choose(bool, a, b):
        return (bool and [a] or [b])[0]

« 过滤列表 | 使用 lambda 函数 »