【Python】白话理解:双向队列collections.deque

(1)浅层认知

collections是python内建标准库的集合模块,功能十分强大。
deque是模块中的双向队列对象,其底层逻辑是双向链表

(2)deque比list更高效

因为采用了双向链表结构,所以可以很方便的塑造「队列」和「栈」,同时成本开销都比list列表要低(时间复杂度和空间复杂度),而且有十分便利的封装方法进行双端操作,几乎与list相关方法名一致、或者在此基础上的拓展。
接下来,我会来论证,如果以后我们要构造队列和栈,为什么要使用deque,而非list。

(3)成本开销

在算法逻辑中,经常会用到队列和栈这两种模型,如果我们用list实现,出队(pop)和插入(insert)时的空间复杂度大约为O(n),deque在出队(pop)和入队(append)时的时间复杂度是O(1)。
为什么?因为链表只需要将指针置空或指向一个新的结点。而,数组都需要把前后的元素整体前移或后移。

(4)双向可操作的封装方法

(4-1)添加元素

(4-1-1)队尾添加元素

仍然是append()。

>>>q=collections.deque([1,2,3,4,5])
>>>q.append(0)
>>>q
(4-1-2)队头添加元素

因为队头在左侧,所以是appendleft()。

>>>q=collections.deque([1,2,3,4,5])
>>>q.appendletf(0)
>>>q
(4-1-3)限制最大长度的添加元素

假如说最多5个元素,当添加第6个元素时,会从另一侧挤掉(溢出)

>>>q=collections.deque([1,2,3,4,5], maxlen=5)
>>>q.append(0)
>>>q
#超过限制长度,队尾增加,队头自动删除
deque([2, 3, 4, 5, 0], maxlen=5)
(4-1-4)插入元素

仍然是insert(插入位置序号,插入的元素值)。

>>>q=collections.deque([1,2,3,4,5])
>>>q.insert(2,7)
>>>q
deque([1, 2, 7, 3, 4, 5])

(4-2)删除操作

(4-2-1)队尾推出元素

仍然是pop()。
同时返回该元素值。

>>>q=collections.deque([1,2,3,4,5])
>>>q.pop()
>>>q
deque([12, 3, 4])
(4-2-2)队头推出元素

因为是左侧的推出,保持一致,因此是popleft()。
同时返回该元素值。

>>>q=collections.deque([1,2,3,4,5])
>>>q.popleft()
>>>q
deque([2, 3, 4, 5])
(4-2-3)删除指定元素

remove(元素值)。因为是链表,无直接的序号索引。

>>>q=collections.deque([1,2,3,4,5])
>>>q.remove(2)
>>>q
deque([1, 3, 4, 5])

(4-3)添加序列

(4-3-1)序列创建方法

开始没有讲deque的创建方法,因为是想先对比添加和删除操作与list的异同,接下来,我们来看deque的创建方法,它有两个参数,

  • 第2个参数maxlen可以固定队列的最大元素数,前面有应用过;
  • 第1个参数,是一个迭代器,如果你把list传进去,它会自动 for in添加每一个元素,实际上就是list转deque,除此以外,无论你放什么,它都会 for in迭代进去,这也是迭代器为什么要叫迭代器的原因,万物皆可for in。
>>>q1=collections.deque()
>>>q2=collections.deque([1,2,3,4,5])
>>>q3=collections.deque("12345")
>>>q4=collections.deque(range(1,6))
>>>q1
>>>q2
>>>q3
>>>q4
deque([])
deque([1, 2, 3, 4, 5])
deque(['1', '2', '3', '4', '5'])
deque([1, 2, 3, 4, 5])

通过观察我们发现,list的表达式是[],而deque没有一对儿专属的符号来表示,它只能是deque([]),从某种意义上讲,deque是不是就是一种特殊的list补集呢?

(4-3-2)队尾添加序列

仍然是extend()。同时,因为传入的参数也是迭代器,可以传入任何可迭代的数据。

>>>q1=collections.deque([1,2,3,4,5])
>>>q2=collections.deque([1,2,3,4,5])
>>>q1.extend([6,7,8])
>>>q2.extend(range(6,10))
>>>q1
>>>q2
deque([1, 2, 3, 4, 5, 6, 7, 8,])
deque([1, 2, 3, 4, 5, 6, 7, 8, 9])
(4-3-3)队头添加元素

因为队头在左侧,所以是extendleft()。

>>>q1=collections.deque([1,2,3,4,5])
>>>q2=collections.deque([1,2,3,4,5])
>>>q1.extendleft([6,7,8])
>>>q2.extendleft(range(6,10))
>>>q1
>>>q2
deque([6, 7, 8, 1, 2, 3, 4, 5])
deque([9, 8, 7, 6, 1, 2, 3, 4, 5])

(5)线程安全

因为是标准库中的封装对象之一,deque是线程安全的,也就是说可以同时从deque集合的左边和右边进行操作而不会有影响。

>>>q=collections.deque([1,2,3,4,5])
>>>q.append(q.popleft())
>>>q
deque([2, 3, 4, 5, 1])

参考引用:Python:【基础语法】 deque()用法

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值