Python如何建立多个值和单个键的映射
作者:TakingCoding4Granted
在Python中,常见的字典只能映射单个键到单个值,若需映射单个键到多值,可以通过将值存储于列表或集合中实现,使用列表可以保持元素插入顺序,而使用集合则可以去重,collections模块的defaultdict类简化了此类多值字典的创建过程
问题
你希望创建一个字典,该字典可以建立多个值和单个键之间的映射(即所谓的多值字典)。
解决方案
在 Python 中,基于普通的字典类 dict
创建的对象一般只可以存储一个键和一个值的映射。
如果你希望存储一个键和多个值之间的映射,你需要将多个值存储存储在另一个容器中,如:列表或集合。
例如,你可能会创建如下所示的字典:
d = { 'a': [1, 2, 3], 'b': [4, 5], } e = { 'a': {1, 2, 3}, 'b': {4, 5}, }
究竟是使用列表还是集合来保存多个值取决于实际需求,即如果你希望保持元素的插入顺序,那么使用列表比较好;如果你希望去除重复元素且不在乎元素的插入顺序,则使用集合更佳。
实际上,下面将看到,通过代码的方式创建上述的字典还是比较麻烦的,需要考虑某个键是否已经在字典中,并据此做不同的处理。
对此,标准模块 collections
中的类 defaultdict
可以使得通过代码创建类似上述字典变得很容易,使用该类创建的对象中,一个显著的特点是,对于不存在的键,在第一次尝试按照键添加值时,该对象做好自动的做好值的初始化。
例如:
>>> from collections import defaultdict >>> d = defaultdict(list) >>> d defaultdict(<class 'list'>, {}) >>> d['a'] [] >>> d defaultdict(<class 'list'>, {'a': []}) >>> d = defaultdict(list) >>> d['a'].append(1) >>> d['a'].append(2) >>> d['b'].append(4) >>> d defaultdict(<class 'list'>, {'a': [1, 2], 'b': [4]}) >>> d = defaultdict(set) >>> d['a'].add(1) >>> d['a'].add(2) >>> d['b'].add(4) >>> d defaultdict(<class 'set'>, {'a': {1, 2}, 'b': {4}})
讨论
如上所述,如果使用普通的字典类 dict
创建对象实现和上述 defaultdict
类创建对象类似的功能,那么对于某个键第一个值的初始化就会比较麻烦。
例如,使用 dict
的初始化可能如下:
>>> pairs >>> [('a', 1), ('a', 2), ('a', 3), ('b', 4), ('b', 5)] >>> d = {} >>> for key, value in pairs: ... if key not in d: ... d[key] = [] ... d[key].append(value) >>> d {'a': [1, 2, 3], 'b': [4, 5]}
如果使用 defaultdict
,那么代码就会很简洁:
>>> d = defaultdict(list) >>> for key, value in pairs: ... d[key].append(value) >d defaultdict(<class 'list'>, {'b': [4, 5], 'a': [1, 2, 3]})
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。