3.6. 映射 list
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:

## 3.6. 映射 list

Python 的强大特性之一是其对 list 的解析，它提供一种紧凑的方法，可以通过对 list 中的每个元素应用一个函数，从而将一个 list 映射为另一个 list。

### 例 3.24. List 解析介绍

    >>> li = [1, 9, 8, 4]
    >>> [elem*2 for elem in li]
    [2, 18, 16, 8]
    >>> li
    [1, 9, 8, 4]
    >>> li = [elem*2 for elem in li]
    >>> li
    [2, 18, 16, 8]

| 为了便于理解它，让我们从右向左看。`li` 是一个将要映射的 list。Python 循环遍历 `li` 中的每个元素。对每个元素均执行如下操作：首先临时将其值赋给变量 `elem`，然后 Python 应用函数 ``elem`*2` 进行计算，最后将计算结果追加到要返回的 list 中。
| 需要注意是，对 list 的解析并不改变原始的 list。
| 将一个 list 的解析结果赋值给对其映射的变量是安全的。不用担心存在竞争情况或任何古怪事情的发生。Python 会在内存中创建新的 list，当对 list 的解析完成时，Python 将结果赋给变量。

让我们回过头来看看位于 第 2 章 的函数 `buildConnectionString` 对 list 的解析：

    ["%s=%s" % (k, v) for k, v in params.items()]

首先，注意到你调用了dictionary `params` 的 `items` 函数。这个函数返回一个 dictionary 中所有数据的 tuple 的 list。

### 例 3.25. `keys`, `values` 和 `items` 函数

    >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
    >>> params.keys()
    ['server', 'uid', 'database', 'pwd']
    >>> params.values()
    ['mpilgrim', 'sa', 'master', 'secret']
    >>> params.items()
    [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]

| Dictionary 的 `keys` 方法返回一个包含所有键的 list。这个 list 没按 dictionary 定义的顺序输出 (记住，元素在 dictionary 中是无序的)，但它是一个 list。
| `values` 方法返回一个包含所有值的 list。它同 `keys` 方法返回的 list 输出顺序相同，所以对于所有的 `n`，`params.values()[n] == params[params.keys()[n]]` 。
| `items` 方法返回一个由形如 `(key，value)` 组成的 tuple 的 list。这个 list 包括 dictionary 中所有的数据。

现在让我们看一看 `buildConnectionString` 做了些什么。它接收一个 list，``params`.`items`()`，通过对每个元素应用字符串格式化将其映射为一个新 list。这个新 list 将与 ``params`.`items`()` 一一对应：新 list 中的每个元素都是 dictionary `params` 中的一个键-值对构成的的字符串。

### 例 3.26. `buildConnectionString` 中的 list 解析

    >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
    >>> params.items()
    [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]
    >>> [k for k, v in params.items()]
    ['server', 'uid', 'database', 'pwd']
    >>> [v for k, v in params.items()]
    ['mpilgrim', 'sa', 'master', 'secret']
    >>> ["%s=%s" % (k, v) for k, v in params.items()]
    ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']

| 请注意我们正在使用两个变量对 list `params.items()` 进行遍历。这是多变量赋值的另一种用法。`params.items()` 的第一个元素是 `('server', 'mpilgrim')`，所以在 list 解析的第一次遍历中，`k` 将为 `'server'`，`v` 将为 `'mpilgrim'`。在本例中，我们忽略了返回 list 中 `v` 的值，而只包含了 `k` 的值，所以这个 list 解析最后等于 ``params`.`keys`()`。
| 这里我们做着相同的事情，但是忽略了 `k` 的值，所以这个 list 解析最后等于 ``params`.`values`()`。
| 用一些简单的 字符串格式化将前面两个例子合并起来 ，我们就得到一个包括了 dictionary 中每个元素的 key-value 对的 list。这个看上去有点像程序的输出结果，剩下的就只是将这个 list 中的元素接起来形成一个字符串了。

### 进一步阅读

- Python Tutorial 讨论了另一种方法来映射 list：使用内置的 `map` 函数。
- Python Tutorial 展示了如何对嵌套 list 的 list 进行解析。