如何使用deque增删数据?今天番茄加速就来讲一下。
基本用法 deque 双端队列,基于list优化了列表两端的增删数据操作。基本用法:
from collections import deque
In [3]: d = deque([3,2,4,0])
In [4]: d.popleft() # 左侧移除元素,O(1)时间复杂度
Out[4]: 3
In [5]: d.appendleft(3) # 左侧添加元素,O(1)时间复杂度
In [6]: d
Out[6]: deque([3, 2, 4, 0])
使用场景
list左侧添加删除元素的时间复杂度都为O(n),所以在Python模拟队列时切忌使用list,相反使用deque双端队列非常适合频繁在列表两端操作的场景。但是,加强版的deque牺牲了空间复杂度,所以嵌套deque就要仔细trade-off:
In [9]: sys.getsizeof(deque())
Out[9]: 640
In [10]: sys.getsizeof(list())
Out[10]: 72
实现原理
cpython实现deque使用默认长度64的数组,每次从左侧移除1个元素,leftindex加1,如果超过64释放原来的内存块,再重新申请64长度的数组,并使用双端链表block管理内存块。
Counter
基本用法
Counter一种继承于dict用于统计元素个数的数据结构,也称为bag 或 multiset. 基本用法:
from collections import Counter
In [14]: c = Counter([1,3,2,3,4,2,2]) # 统计每个元素的出现次数
In [17]: c
Out[17]: Counter({1: 1, 3: 2, 2: 3, 4: 1})
# 除此之外,还可以统计最常见的项
# 如统计第1最常见的项,返回元素及其次数的元组
In [16]: c.most_common(1)
Out[16]: [(2, 3)]
使用场景
基本的dict能解决的问题就不要用Counter,但如遇到统计元素出现频次的场景,就不要自己去用dict实现了,果断选用Counter.
需要注意,Counter统计的元素要求可哈希(hashable),换句话说如果统计list的出现次数就不可行,不过list转化为tuple不就可哈希了吗.
实现原理 Counter实现基于dict,它将元素存储于keys上,出现次数为values.