目录
- 问题
- 解决方案
- 讨论
问题
如果希望能够将一个键(key)映射到多个值(value)上,那么应该如何创建这个字典?(即所谓的一键多值字典 [multidict])
解决方案
字典是一种关联容器,每个键都映射到一个单独的值上。如果想让键映射到多个值,那么就需要将这多个值保存在另一个容器如列表或集合中。
# 以列表作为容器存储多个值
d = {'a': [1, 2, 3],'b': [4, 5]
}# 以集合作为容器存储多个值
e = {'a': {1, 2, 3},'b': {4, 5}
}
选择要使用列表还是集合,取决于应用的意图。
- 如果希望保存元素插入的顺序,建议使用列表。
- 如果希望消除重复元素,且不介意乱序,建议使用集合。
而在 python 中,提供 collections
模块可以方便地创建这样的字典。
from collections import defaultdictd = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
...
b = defaultdict(set)
b['a'].add(1)
b['a'].add(2)
b['b'].add(4)
...
关于 defaultdict
需要注意的是,其会自动初始化第一个值,这样只需关注添加元素即可。
讨论
其实原则上构建一个一键多值的字典是很容易的。但是在初始化操作中,就能体现出 collections
模块的优势所在。
pairs = [('apple', 'fruit'),('carrot', 'vegetable'),('apple', 'red')
]d = {}
for key, value in pairs:if key not in d:d[key] = []d[key].append(value)
上述代码中,循环遍历 pairs 中的每个元素。
if key not in d
:检查 d 中是否已经有了这个 key。如果没有,d[key] = []
在 d 中创建一个新的键值对,其中键是 key,值是一个空列表。d[key].append(value)
则是将 value 追加到与 key 相关联的列表中。- 最终,d 会包含从 pairs 中提取的所有键值对,其中每个键都映射到一个可能包含多个值的列表。
而下述代码,实现同样的功能,通过调用 collections.defaultdict
函数。
pairs = [('apple', 'fruit'),('carrot', 'vegetable'),('apple', 'red')
]for key, value in pairs:d[key].append(value)