当前位置:   article > 正文

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

python 双向队列

(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
  • 1
  • 2
  • 3
(4-1-2)队头添加元素

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

>>>q=collections.deque([1,2,3,4,5])
>>>q.appendletf(0)
>>>q
  • 1
  • 2
  • 3
(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)
  • 1
  • 2
  • 3
  • 4
  • 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])
  • 1
  • 2
  • 3
  • 4

(4-2)删除操作

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

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

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

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

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

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

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

(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])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过观察我们发现,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])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
(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])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(5)线程安全

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/611413
推荐阅读
相关标签
  

闽ICP备14008679号