1.13. 映射列表

Python的强大特性之一是列表理解(list comprehension),它提供一种紧凑的方法,可以通过对列表的每个元素应用一个函数,从而将一个列表映射为另一个列表。

例 1.30. 列表理解介绍

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

为了理解它,让我们从右向左看它。 li 是一个将要映射的列表。Python循环遍历 li 一次一个元素,临时将每个元素的值赋给变量 elem。然后Python使用函数 elem*2 ,接着将结果追加到返回列表中。

2 请注意列表理解并不改变原始的列表。
3

将一个列表理解的结果赋值给你正在对其映射的变量是安全的。不用担心存在竞争情况或任何古怪事情的发生。Python在内存中创建新的列表,当列表理解完成时,Python将结果赋给变量。

例 1.31. 在 buildConnectionString 中的列表理解

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

首先,注意到你调用了字典 paramsitems 函数。这个函数返回一个字典中所有数据的元组的列表。

例 1.32. keys, values, 和 items

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

字典的 keys 方法返回一个所有键字的列表。这个列表不按字典定义的顺序(记住,元素在字典中是无序的),但它是一个列表。

2

values 方法返回一个所有值的列表。这个列表按以 keys 返回的列表的顺序,所以对于所有的 n ,params.values()[n] == params[params.keys()[n]]

3 items 方法返回形式为(key, value) 的元组的一个列表。这个列表包括字典中所有的数据。

现在让我们看一看 buildConnectionString 做了些什么。它接收一个列表,params.items(),通过对每个元素应用字符串格式化将其映射为一个新列表。这个新列表将拥有与 params.items() 一样的元素数量,但在新列表中的每个元素都将是包括了从字典 params 来的一个键字和其相连的值的字符串。

例 1.33. 在 buildConnectionString 中的列表理解,一步接一步

>>> 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()]                1
['server', 'uid', 'database', 'pwd']
>>> [v for k, v in params.items()]                2
['mpilgrim', 'sa', 'master', 'secret']
>>> ["%s=%s" % (k, v) for k, v in params.items()] 3
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
1

请注意我们正在使用两个变量来对 params.items() 列表进行遍历。这是多变量赋值的另一种用法。 params.items() 的第一个元素是 ('server', 'mpilgrim'),所以在列表理解的第一次遍历中, k 将为 'server'v 将为 'mpilgrim'。在本例中,我们忽略了返回列表中 v 的值,而只包含了 k 的值,所以这个列表理解最后等于 params.keys()。(在实际的代码中,你将不会真正使用与些类似的列表理解,它只是一个极为简化的例子,以便让你能够了解在这里发生了些什么。)

2

这里我们做着相同的事情,但是忽略了 k 的值,所以这个列表理解最后等于 params.values()

3

用一些简单的字符串格式化将前面两个例子合并起来 ,我们就得到一个包括了字典每个元素的键-值对列表。这个看上去有点象程序的输出,剩下的就只是将这个列表中的元素接起来形成一个字符串了。

进一步阅读