# 双向队列 双向队列模块`collections.deque` 是一种线程安全,可快速从两端添加和删除元素的数据结构。如果想要一种数据结构存放最近频繁使用几个元素,那么双向队列是不二选择。当然列表也可以作为一种当作双向队列,把`list.append`方法和 `list.pop` 方法合起来使用,当然也可以达到双向队列的入栈和出栈,模拟出先进先出的双向队列数据结构,但是列表的操作是牵扯到移动列表里的所有元素位置,这样操作耗时且性能有限,所以还是采用`collections.deque` 比较好。 ## 一、创建双向队列 ```python from collections import deque dq = deque(range(10), maxlen=10) dq deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) ``` 1、创建双向队列需要导入模块`collections.deque`。 2、`maxlen` 是一个可选参数,代表这个队列可以容纳的元素数量,一旦设定后,这个属性的值就不可更改了。一旦设定,那么这个双向队列的数据结构长度就是确定的。 ## 二、操作双向队列 列表和双向队列的方法 | 方法 | 列表 | 双向队列 | 描述 | | ------------------------ | ---- | -------- | -------------------------------------- | | s.\__add__(s2) | y | | s + s2,拼接 | | s.\__iadd__(s2) | y | y | s += s2,就地拼接 | | s.append(e) | y | y | 在末端,最后一个元素之后,添加一个元素 | | s.appendleft(e) | | y | 在前端,第一个元素之前,添加一个元素 | | s.clear() | y | y | 删除所有元素 | | s.\__contains__(e) | y | | s是否含有e | | s.copy() | y | | 列表浅复制 | | s.\__copy__() | | y | 双向队列对copy.copy(浅复制)的支持 | | s.count(e) | y | y | s中e出现的次数 | | s.\__delitem__(p) | y | y | 把位置p的元素移除 | | s.extend(i) | y | y | 将可迭代对象i中的元素添加到尾部 | | s.extendleft(i) | | y | 将可迭代对象i中的元素添加到头部 | | s.\__getitem__(p) | y | y | s[p],读取位置p的元素 | | s.index(e) | y | | 找到e在序列中第一次出现的位置 | | s.insert(p, e) | y | | 在位于p的元素之前插入元素e | | s.\__iter__() | y | y | 返回迭代器 | | s.\__len__() | y | y | len(s),序列的长度 | | s.\__mul__(n) | y | | s*n,重复拼接 | | s.\__imul__(n) | y | | s*=n,就地重复拼接 | | s.\__rmul__(n) | y | | n*s,反向重复拼接 | | s.pop() | y | y | 移除最后一个元素并返回它的值 | | s.popleft() | | y | 移除第一个元素并返回它的值 | | s.remove(e) | y | y | 移除s中第一次出现e的元素 | | s.reverse() | y | y | 反转序列中元素位置 | | s.\__reversed__() | y | y | 返回一个从尾部开始扫描元素的迭代器 | | s.rotate(n) | | y | 把n个元素从队列的一端移到另一端 | | s.\__setitem__(p, e) | y | y | s[p]=e,把位于p位置的元素替换成e | | s.sort([key], [reverse]) | y | | 就地排序序列,可选key和reverse | ```python dq.rotate(3) dq deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10) dq.rotate(-4) dq deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10) #队列的旋转操作接受一个参数 n,当 n > 0 时,队列的最右边的 n个元素会被移动到队列的左边。当 n < 0 时,最左边的 n 个元素会被移动到右边。 dq.appendleft(3.14) dq deque([3.14, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) dq.extend([11, 22, 33]) dq deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10) # 当试图对一个已满(len(d) == d.maxlen)的队列做尾部添加操作的时候,返过来一样,当对一个已满长度的队列做头部添加时,尾部的元素会溢出. dq.extendleft([10, 20, 30, 40]) dq deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10) #迭代器对象会逆序放到队列的头部 ``` ## 三、其他队列模块 - `queue` :包括同步线程安全类`Queue` , `LifoQueue`, `PriorityQueue` - `multiprocessing` - `asyncio`:`Queue` , `LifoQueue`, `PriorityQueue` , `JoinableQueue` - `heapq`:有`heappush`和 `heappop` 方法