Python collections中的双向队列deque简单介绍详解


Posted in Python onNovember 04, 2019

前言

在python神书《Python+Cookbook》中有这么一段话:在队列两端插入或删除元素时间复杂度都是 O(1) ,而在列表的开头插入或删除元素的时间复杂度为 O(N)。
于是就想验证下。

简单使用

基本代码

from collections import deque
q = deque(maxlen=4)#有固定长度的双向队列
qq = deque() #无固定长度
print(dir(q))#看看有哪些可用方法或属性

结果:

['__add__', '__bool__', '__class__', '__contains__', '__copy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'appendleft', 'clear', 'copy', 'count', 'extend', 'extendleft', 'index', 'insert', 'maxlen', 'pop', 'popleft', 'remove', 'reverse', 'rotate']

看到可以append,pop,insert,clear等,还可以像List一样用中括号 [] 对某个index获取或设置值。因为是双向队列,所以也有左操作函数:appendleft,popleft。额外的还要反转函数reverse,计数函数count。

使用ipython验证

In [1]: from collections import deque
…: q = deque(maxlen=4)#有固定长度的双向队列
…: qq = deque() #无固定长度
…: print(dir(q))#看看有哪些可用方法或属性
[‘add', ‘bool', ‘class', ‘contains', ‘copy', ‘delattr', ‘delitem', ‘dir', ‘doc', ‘eq', ‘format', ‘ge', ‘getattribute', ‘getitem', ‘gt', ‘hash', ‘iadd', ‘imul', ‘init', ‘init_subclass', ‘iter', ‘le', ‘len', ‘lt', ‘mul', ‘ne', ‘new', ‘reduce', ‘reduce_ex', ‘repr', ‘reversed', ‘rmul', ‘setattr', ‘setitem', ‘sizeof', ‘str', ‘subclasshook', ‘append', ‘appendleft', ‘clear', ‘copy', ‘count', ‘extend', ‘extendleft', ‘index', ‘insert', ‘maxlen', ‘pop', ‘popleft', ‘remove', ‘reverse', ‘rotate']
In [2]: q
Out[2]: deque([])
In [3]: q.append(1)
In [4]: q.insert(0,33)
In [6]: q
Out[6]: deque([33, 1])
In [8]: q.appendleft(44)
In [9]: q
Out[9]: deque([44, 33, 1])
In [10]: q.pop()
Out[10]: 1
In [12]: q[1]
Out[12]: 33
In [13]: q
Out[13]: deque([44, 33])
In [14]: q.reverse()
In [15]: q
Out[15]: deque([33, 44])
In [17]: q.clear()
In [18]: q
Out[18]: deque([])

性能测试

pop和append

#coding:utf8
import datetime,time
from collections import deque
D = deque()
L=[]
def calcTime(func):  
  def doCalcTime():
    sst = int(time.time()*1000)
    func()
    eed = int(time.time()*1000)
    print(func,'cost time:',eed-sst,'ms')
  return doCalcTime

@calcTime
def didDeque():
  for i in range(0,10000000):
    D.append(i)
  while D:
    D.pop()

@calcTime
def didList():
  for i in range(0,10000000):
    L.append(i)
  while L:
    L.pop()
    
if __name__=='__main__':
  didDeque()
  print("------------")
  didList()

运行结果:

<function didDeque at 0x000002D6912A4D08> cost time: 1924 ms
------------
<function didList at 0x000002D6912D4048> cost time: 2420 ms

是快了一些。

insert

#coding:utf8
import datetime,time
from collections import deque
D = deque()
L=[]
def calcTime(func):  
  def doCalcTime():
    sst = int(time.time()*1000)
    func()
    eed = int(time.time()*1000)
    print(func,'cost time:',eed-sst,'ms')
  return doCalcTime

@calcTime
def didDeque():
  for i in range(0,100000):
    D.insert(5,i)
    
@calcTime
def didList():
  for i in range(0,100000):
    L.insert(5,i)

if __name__=='__main__':
  didDeque()
  print("------------")
  didList()

运行结果:

<function didDeque at 0x0000021367F06D08> cost time: 32 ms
------------
<function didList at 0x0000021367F34048> cost time: 3499 ms

快了两个数量级。想想也明白,一个是链表,插入的时候只需要改变指针指向,而List是连续空间,需要移动一大堆的元素。

计算移动平均

>>> import numpy as np
>>> from collections import deque
>>> q=deque(maxlen=5)
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q.append(4)
>>> q.append(5)
>>> q.append(6)
>>> q
deque([2, 3, 4, 5, 6], maxlen=5)
>>> np.array(q).mean()
4.0

结语

如果可以,数据量大的时候,用deque代替List的能提升一部分性能。 而由于deque是队列可以设定固定长度,实现先入先出。 那么,如在计算移动平均的时候可以使用,很快捷方便。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
各种Python库安装包下载地址与安装过程详细介绍(Windows版)
Nov 02 Python
Python最小二乘法矩阵
Jan 02 Python
Django uwsgi Nginx 的生产环境部署详解
Feb 02 Python
python中字符串数组逆序排列方法总结
Jun 23 Python
python SVM 线性分类模型的实现
Jul 19 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
Sep 20 Python
wxpython+pymysql实现用户登陆功能
Nov 19 Python
pytorch如何冻结某层参数的实现
Jan 10 Python
Python中的整除和取模实例
Jun 03 Python
python线程池 ThreadPoolExecutor 的用法示例
Oct 10 Python
Python脚本打包成可执行文件过程解析
Oct 20 Python
Python 无限级分类树状结构生成算法的实现
Jan 21 Python
Python 下载及安装详细步骤
Nov 04 #Python
Django框架表单操作实例分析
Nov 04 #Python
ubuntu 18.04 安装opencv3.4.5的教程(图解)
Nov 04 #Python
Django框架模板用法入门教程
Nov 04 #Python
python matplotlib折线图样式实现过程
Nov 04 #Python
Django框架创建项目的方法入门教程
Nov 04 #Python
Python jieba库用法及实例解析
Nov 04 #Python
You might like
PHP获取不了React Native Fecth参数的解决办法
2016/08/26 PHP
thinkPHP5框架接口写法简单示例
2019/08/05 PHP
学习js所必须要知道的一些
2007/03/07 Javascript
JS 继承实例分析
2008/11/04 Javascript
js 父窗口控制子窗口的行为-打开,关闭,重定位,回复
2010/04/20 Javascript
javascript下string.format函数补充
2010/08/24 Javascript
JS(JQuery)操作Array的相关方法介绍
2014/02/11 Javascript
ie9 提示'console' 未定义问题的解决方法
2014/03/20 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
JavaScript监听手机物理返回键的两种解决方法
2017/08/14 Javascript
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
写一个Vue Popup组件
2019/02/25 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
es6 filter() 数组过滤方法总结
2019/04/03 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
python出现&quot;IndentationError: unexpected indent&quot;错误解决办法
2017/10/15 Python
python批量读取txt文件为DataFrame的方法
2018/04/03 Python
VSCode下配置python调试运行环境的方法
2018/04/06 Python
学python安装的软件总结
2019/10/12 Python
Python中itertools的用法详解
2020/02/07 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
PIL包中Image模块的convert()函数的具体使用
2020/02/26 Python
马来西亚网上购物:Youbeli
2018/03/30 全球购物
北京一家公司的.net开发工程师笔试题
2012/04/17 面试题
珍珠奶茶店创业计划书
2014/01/11 职场文书
小学毕业典礼主持词
2014/03/27 职场文书
新闻编辑专业自荐信
2014/07/02 职场文书
2014乡镇党政班子四风问题思想汇报
2014/09/14 职场文书
个人作风建设总结
2014/10/23 职场文书
公司前台接待岗位职责
2015/04/03 职场文书
企业财务管理制度范本
2015/08/04 职场文书
python实现自动清理文件夹旧文件
2021/05/10 Python
Django使用echarts进行可视化展示的实践
2021/06/10 Python
PYTHON InceptionV3模型的复现详解
2022/05/06 Python
MySQL串行化隔离级别(间隙锁实现)
2022/06/16 MySQL