在字典中将键映射到多个值上

在某些情况下,我们想要一个能够将键映射为多个值的字典。对于常规情况下,我们可以这样创建字典:

d = {
'a' : [1, 2, 3],
'b' : [4, 5]
}
e = {
'a' : [1, 2, 3],
'b' : [4, 5]
}

要使用列表还是集合完全取决于应用的意图。如果你希望保留元素插入的顺序,就使用列表,反之,则使用集合。对于方便创建字典,可以利用collection模块的defaultdict类。它的一个特点就是它会初始化第一个值,这样就只需关注元素就好

注意:对于defaultdict,他会为了未来的访问而自动创建字典表项,如果不想要,就用setdefault()来取代

原则上,构建一个一键多值的字典是很容易的,但是如果试着对着第一个值进行初始化,你就会发现这会变得非常杂乱。在这个时候,使用defaultdict代码就会清晰很多

让字典保持有序

假如说有这么样一个字典,它在Z做迭代或者序列化操作的时候,也能控制其中元素的顺序。在这个时候,我们就可以用collections模块中的OrderedDict类,当字典做迭代的时候,它会严格按照元素的初始添加的顺序进行。

from collection improt OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
for key in d:
print(key, d[key])

如果当你想构建一个映射结构以便以后对其序列化或者编码成另一种格式的时候,OrderedDict就会特别有用。实际上,OrderedDict内部维护了一个双向链表,它会根据元素加入的顺序来排列键的位置.但是请注意,使用OrderedDict虽然方便,但是它的大小是普通字典的两倍多,因此,如果你想构建一个涉及大量OrderedDict示例的数据结构,它就会占用非常大的内存空间,从而导致运行效率下降。

关于字典的计算问题

假如我们想在字典上实现对数据的计算的时候,就可以利用字典的value()的方法来解决这个问题,大概是这个样子的:

min(prices.value())
max(prices.value())

如果提供一个key参数传递给min()和max(),就能得到最大值和最小值所对应的键是什么,就像这样:

min(prices, key=lambda k: prices[k])
max(prices, key=lambda k: prices[k])

但是,要得到最小值还是需要进行一次查找

min_value = prices[min(prices, key=lambda k: prices[k])]

这个利用了zip()的解决方案是通过将字典的键-值对反转为值-键对序列来解决这个问题的

当在这样的元组上执行比较操作的时候,值会先进行比较,然后才是键。但是注意:当涉及(value, key)比较的时候,如果碰巧有多个条目拥有相同的value值,那么此时的key将用来作为判定结果的依据。

在两个字典中寻找共同点

有时候你可能想把两个字典相互比较,寻找共同点。考虑如下两个字典:

d = {
'a' : [1, 2, 3],
'b' : [4, 5]
}
e = {
'a' : [1, 2, 3],
'b' : [4, 5]
}

这个时候要找出这两个字典的共同之处,只需要通过keys()和items()来进行集合查找就好

#找相同
a.keys() & b.keys()
#找a不在b里的元素
a.keys() - b.keys()
#找(key, value)对的相同
a.items() & b.items()

参考书目:

《Python CookBook》作者:【美】 David Beazley, Brian K. Jones

Github地址:PacktPublishing/Modern-Python-Cookbookgithub.com