在Python中,字典是以散列映射的方式实现的,在插入、删除和访问元素方面的时间复杂度都是O(1)。
在Python3.5及之前的版本中,字典是无序集合,但从Python3.6开始,字典能够保留元素的插入顺序
散列映射就是将key和value关联的一种数据结构,散列函数就是哈希(hash)函数。熟悉哈希函数的朋友应该知道,哈希函数的冲突是不可避免的,但我们平时在使用Python的字典时,无需考虑这个因素,因为大多数情况下,默认的冲突解决方案都是有效的。
上一节“Python高性能计算之列表”中我们讲到过一个库–collections
,里面有双端队列可供我们选择,这一节我们再讲一个collections
中提高字典工作相率的方法。
当我们对列表中的元素个数进行统计,并将统计结果写入到字典中时,我们往往会这么写:
def counter_dict(lst):
counter = {}
for item in lst:
if item not in counter:
counter[item] = 1
else:
counter[item] += 1
return counter
函数调用:
numLst = np.random.randint(0,5,10)
cnt_dict = counter_dict(numLst)
下面来看第一种优化方法:
在collections
中有个defaultdict
函数,它可以生成一个字典,并给每个新键自动指定一个默认值,所以我们可以把上面的代码简写为:
from collections import defaultdict
def counter_defaultdict(lst):
counter = defaultdict(int)
for item in lst:
counter[item] += 1
return counter
第二种优化方法,其中collections
中还提供了一种更为简单的方法:
from collections import Counter
counter = Counter(numLst)
这三种实现方式的时间复杂度都是O(N),但效率却大不相同,下面来对比:
numLst = np.random.randint(0,10,10000)
%timeit cntDict = counter_dict(numLst)
2.02 ms ± 42.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit cntDefDict = counter_defaultdict(numLst)
1.66 ms ± 2.57 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit cnt = Counter(numLst)
1.29 ms ± 33.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
可以看到,使用Counter的效率最高。
系列文章:
1. Python高性能计算之列表
2. Python高性能计算之字典
3. Python高性能计算之堆
4. Python高性能计算之字典树
5. Python常用操作的复杂度
微信公众号:Quant_Times