python进阶学习笔记-双向队列deque

列表用作队列

利用 .append 和 .pop 方法,我们可以把列表当作栈或者队列来用(比如,把 .append和 .pop(0) 合起来用,就能模拟栈的“先进先出”的特点)。但是删除列表的第一个元素(抑或是在第一个元素之前添加一个元素)之类的操作是很耗时的,因为这些操作会牵扯到移动列表里的所有元素。

双向队列

collections.deque 类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。而且如果想要有一种数据类型来存放“最近用到的几个元素”,deque 也是一个很好的选择。这是因为在新建一个双向队列的时候,你可以指定这个队列的大小,如果这个队列满员了,还可以从反向端删除过期的元素,然后在尾端添加新的元素。
但是从队列中间删除元素的操作会慢一些,因为它只对在头尾的操作进行了优化。
接下来的示例中有几个双向队列的典型操作。

eg:

>>> from collections import deque
>>> dq = deque(range(10), maxlen=10) #maxlen 是一个可选参数,代表这个队列可以容纳的元素的数量,而且一旦设定,这个属性就不能修改了
>>> dq
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.rotate(3) #队列的旋转操作接受一个参数 n,当 n > 0 时,队列的最右边的 n 个元素会被移动到队列的左边。当 n < 0 时,最左边的 n 个元素会被移动到右边
>>> 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)
>>> dq.appendleft(-1) #当试图对一个已满(len(d) == d.maxlen)的队列做尾部添加操作的时候,它头部的元素会被删除掉。注意在下一行里,元素 0 被删除了
>>> dq
deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.extend([11, 22, 33]) #在尾部添加 3 个元素的操作会挤掉 -1、1 和 2,这里是添加了一个列表
>>> dq
deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10)
>>> dq.extendleft([10, 20, 30, 40]) #extendleft(iter) 方法会把迭代器里的元素逐个添加到双向队列的左边,因此迭代器里的元素会逆序出现在队列里
>>> dq
deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)

语法:deque(序列, maxlen=n),创建一个容量为n的序列队列,但是两个参数都是可选的,如果没有指定序列,默认创建一个空序列,若没有指定长度,默认无限长度。可以存储n个数,当添加第n+1个数时,第1个数自动被挤出。

deque创建的对象所支持的方法(通过 .方法 方式调用即可):
append(x):将x添加到双端队列的右侧。
appendleft(x):将x添加到双端队列的左侧。
clear():删除deque中的所有元素,使其长度为0。
copy():创建一个deque的浅表副本。3.5版本中的新功能。
count(x):计算deque元素的数量等于x。3.2版本中的新功能。
extend(iterable):通过追加iterable参数中的元素来扩展双端队列的右侧。
extendleft(iterable):通过追加iterable中的元素来扩展双端队列的左侧。请注意,一系列左边追加结果会颠倒迭代参数中元素的顺序。
index(x[, start[, stop]]):返回deque中的x的位置(在索引开始处或索引停止之前)。如果未找到,则返回第一个匹配或引发ValueError。
insert(i, x):将x插入位置i处的deque中。3.5版本中的新功能。如果插入会导致有界的deque超出maxlen,则会引发IndexError。
pop():从deque的右侧移除并返回一个元素。 如果没有元素存在,则引发IndexError。
popleft():从deque的左侧移除并返回一个元素。 如果没有元素存在,则引发IndexError。
remove(value):删除第一次出现的值。 如果找不到,则会引发ValueError。
reverse():反序排列deque的元素,然后返回None。New in version 3.2。
rotate(n):向右旋转deque n个步。 如果n为负数,则向左旋转。也就是当deque不为空时,向右旋转一个等同d.appendleft(d.pop()),向左旋转一个等同d.append(d.popleft())。

列表和双向队列方向对比(这里直接上的截图):
python进阶学习笔记-双向队列deque_第1张图片
python进阶学习笔记-双向队列deque_第2张图片
python进阶学习笔记-双向队列deque_第3张图片
python进阶学习笔记-双向队列deque_第4张图片

其他操作队列的标准库

1.queue

提供了同步(线程安全)类 Queue、LifoQueue 和 PriorityQueue,不同的线程可以利用这些数据类型来交换信息。这三个类的构造方法都有一个可选参数 maxsize,它接收正整数作为输入值,用来限定队列的大小。但是在满员的时候,这些类不会扔掉旧的
元素来腾出位置。相反,如果队列满了,它就会被锁住,直到另外的线程移除了某个元素而腾出了位置。这一特性让这些类很适合用来控制活跃线程的数量。

2.multiprocessing

这个包实现了自己的 Queue,它跟 queue.Queue 类似,是设计给进程间通信用的。同时还有一个专门的 multiprocessing.JoinableQueue 类型,可以让任务管理变得更方便。

3.asyncio

Python 3.4 新提供的包,里面有 Queue、LifoQueue、PriorityQueue 和JoinableQueue,这些类受到 queue 和 multiprocessing 模块的影响,但是为异步编程里的任务管理提供了专门的便利。

4.heapq

跟上面三个模块不同的是,heapq 没有队列类,而是提供了 heappush 和 heappop方法,让用户可以把可变序列当作堆队列或者优先队列来使用。

这几个库就暂时先不深入了解了,毕竟我还没有使用到它们,哈哈哈哈哈

今天的分享就到这里结束咯~有什么问题请大家指出,我一定会及时修改 ~ ~ ~

你可能感兴趣的:(python进阶学习)