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

问题

我们想要将一个列表,里面是(key, value)这样的键值对元组,转换成一个key相同的value的字典,如下所示:

1
2
3
4
5
6
7
data = [('a', 1), ('a', 2), ('a', 3), ('b', 4), ('b', 5)]

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

解决

通常来说,要进行这样的转换是很容易的,但很多时候会写出下面不够 Pythonic 的代码:

1
2
3
4
5
result = {}
for (key, value) in data:
if key not in result:
result[key] = []
result[key].append(value)

这时我们可以使用 collections 模块中的 defaultdict 类。defaultdict 的一个特点就是它会自动初始化第一个值,这样只需关注添加元素即可。例如:

1
2
3
4
5
from collections import defaultdict

result = defaultdict(lits)
for (key, value) in data:
result[key].append(value)

关于 defaultdict , 需要注意的一个地方是,它会自动创建字典表项以待稍后的访问(即使这些表项当前在字典中还没找到)。如果不想要这个功能,可以在普通的字典上调用 setdefault() 方法来取代。例如:

1
2
3
result = dict()
for (key, value) in data:
result.setdefault(key, []).append(value)

参考:

  • Python Cookbook