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中input()与raw_input()的区别分析
Feb 27 Python
Python 序列的方法总结
Oct 18 Python
高效测试用例组织算法pairwise之Python实现方法
Jul 19 Python
Python实现字符串匹配算法代码示例
Dec 05 Python
Python操作Oracle数据库的简单方法和封装类实例
May 07 Python
Python selenium实现微博自动登录的示例代码
May 16 Python
python celery分布式任务队列的使用详解
Jul 08 Python
Python中断多重循环的思路总结
Oct 04 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
Jan 12 Python
使用PyQt5实现图片查看器的示例代码
Apr 21 Python
Python基于DB-API操作MySQL数据库过程解析
Apr 23 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
Jun 28 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读取IMAP邮件
2006/10/09 PHP
php print EOF实现方法
2009/05/21 PHP
PHP 输出简单动态WAP页面
2009/06/09 PHP
php set_magic_quotes_runtime() 函数过时解决方法
2010/07/08 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
2014/06/25 PHP
iOS10推送通知开发教程
2016/09/19 PHP
基于swoole实现多人聊天室
2018/06/14 PHP
javascript动画效果类封装代码
2007/08/28 Javascript
Document 对象的常用方法
2009/07/31 Javascript
深入认识javascript中的eval函数
2009/11/02 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
jQuery autocomplate 自扩展插件、自动完成示例代码
2011/03/28 Javascript
js 验证密码强弱的小例子
2013/03/21 Javascript
用html+css+js实现的一个简单的图片切换特效
2014/05/28 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
浅析JavaScript回调函数应用
2016/05/22 Javascript
Jquery中map函数的用法
2016/06/03 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
Vue.js实战之组件的进阶
2017/04/04 Javascript
AngularJS实现根据不同条件显示不同控件
2017/04/20 Javascript
canvas绘制爱心的几种方法总结(推荐)
2017/10/31 Javascript
Python IDLE入门简介
2017/12/08 Python
mac系统安装Python3初体验
2018/01/02 Python
Python 实现使用dict 创建二维数据、DataFrame
2018/04/13 Python
python用插值法绘制平滑曲线
2021/02/19 Python
Python线程指南分享
2019/11/19 Python
Speedo澳大利亚官网:全球领先游泳品牌
2018/02/04 全球购物
美国室内和室外装饰花盆购物网站:ePlanters
2019/03/22 全球购物
医者仁心观后感
2015/06/17 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
趣味运动会标语口号
2015/12/26 职场文书
《实心球》教学反思
2016/02/23 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书