python defaultdict用法
pre:
python 生成字典可以使用{},可以使用dict,生成的字典在 dict[key]取值时如果key不存在会报错
defaultdict
当字典里的key不存在但是取值时不会报错,会返回一个默认值,默认值取决于初始化的工厂函数
-
dict =defaultdict(factory_function)
-
factory_function
- factory_function为list时,默认值为[]
- factory_function为str时,默认值为"",即空字符串
- factory_function为set时,默认值为set()
- factory_function为int时,默认值为0
-
exp(list)
from collections import defaultdict # list 第一次返回空列表,可以实现数据合并 s = [('red', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] d = defaultdict(list) for k, v in s: d[k].append(v) print(d) # defaultdict(<class 'list'>, {'red': [1, 1], 'blue': [2, 4], 'yellow': [3]})
-
exp(int)
from collections import defaultdict # int 初始化返回0,实现计数 str = "aswewesdcawreqmo" d = defaultdict(int) for s in str: d[s]+=1 print(d) # defaultdict(<class 'int'>, {'a': 2, 's': 2, 'w': 3, 'e': 3, 'd': 1, 'c': 1, 'r': 1, 'q': 1, 'm': 1, 'o': 1})
python2 python3 dict区别
-
原理
python3.6 之前3.6之前字典底层维护一张hash表, 如果把该表看为一个数组, 即维护一个二维数组, 初始状态默认8行3列, 第一列为key值hash结果, 第二列为key, 第三列 为value 对key值使用hash函数, 得到的hash值跟现有长度取余, 余数即为键值对在数组中的下标, 查找也是先获取下标根据下标取值, 所以时间复杂度为O(1) 由于先计算得到下标再根据下表插入键值对, 有两个问题:一、hash冲突(开放寻址法;再hash) 二、字典键值对在列表中存储顺序没有与插入顺序保持一致
python3.6 之后
3.6之后字典底层维护两张表, 一张表为一维数组, 存放下标, 一张表为二维数组, 初始默认为空, 新增键值对在现有键值对后面添加 对一个键值对进行hash取余后得到一个整数, 该整数作为第一个一维数组的下标, 对应位置存放键值对的下标, 即按照键值对顺序排列的列表下标 取值时先得到整数下标, 拿到对应的第一个列表中的index值, 使用该index值获取二维数组中的键值对, 这样就保证了键值对存储的顺序性
-
方法:keys() items() values()
- python2 中上述方法返回list对象, 可直接遍历
- python2 中上述方法分别返回dict_keys、dict_items、dict_values对象, 不可直接按照索引方式取值, 可用for循环遍历, 内存开销更小