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服务并自动启动服务示例
Apr 17 Python
Python使用tablib生成excel文件的简单实现方法
Mar 16 Python
Python处理文本文件中控制字符的方法
Feb 07 Python
Python基于正则表达式实现检查文件内容的方法【文件检索】
Aug 30 Python
Python cookbook(数据结构与算法)让字典保持有序的方法
Feb 18 Python
python用户管理系统
Mar 13 Python
python 显示数组全部元素的方法
Apr 19 Python
python+pandas分析nginx日志的实例
Apr 28 Python
树莓派+摄像头实现对移动物体的检测
Jun 22 Python
常用python爬虫库介绍与简要说明
Jan 25 Python
Python GUI编程学习笔记之tkinter事件绑定操作详解
Mar 30 Python
python爬取音频下载的示例代码
Oct 19 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
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
php+mysql实现的无限分类方法类定义与使用示例
2020/05/27 PHP
JQuery触发radio或checkbox的change事件
2012/12/18 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
Jquery通过Ajax访问XML数据的小例子
2013/11/18 Javascript
PHP配置文件php.ini中打开错误报告的设置方法
2015/01/09 PHP
javascript动态修改Li节点值的方法
2015/01/20 Javascript
JS实现仿Windows7风格的网页右键菜单效果代码
2015/09/11 Javascript
Javascript实现倒计时(防页面刷新)实例
2016/12/13 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
微信小程序的分类页面制作
2017/06/27 Javascript
解决webpack -p压缩打包react报语法错误的方法
2017/07/03 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
react实现菜单权限控制的方法
2017/12/11 Javascript
最适应的vue.js的form提交涉及多种插件【推荐】
2018/08/27 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
详解Vue 单文件组件的三种写法
2020/02/19 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
element-ui和vue表单(对话框)验证提示语(残留)清除操作
2020/09/11 Javascript
微信小游戏中three.js离屏画布的示例代码
2020/10/12 Javascript
Python 实现字符串中指定位置插入一个字符
2018/05/02 Python
python处理“
2019/06/10 Python
Python3网络爬虫中的requests高级用法详解
2019/06/18 Python
Python手绘可视化工具cutecharts使用实例
2019/12/05 Python
Python 带星号(* 或 **)的函数参数详解
2021/02/23 Python
SHEIN香港:价格实惠的女性时尚服装
2018/08/14 全球购物
25道Java面试题集合
2013/05/21 面试题
护理学中专毕业生求职信
2013/11/11 职场文书
咖啡馆创业计划书
2014/01/26 职场文书
审计班子对照检查材料
2014/08/27 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
2014保险公司个人工作总结
2014/12/09 职场文书
男方家长婚礼致辞
2015/07/27 职场文书
2015年四年级班主任工作总结
2015/10/22 职场文书
Python实战之用tkinter库做一个鼠标模拟点击器
2021/04/27 Python