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 相关文章推荐
Flask SQLAlchemy一对一,一对多的使用方法实践
Feb 10 Python
Python实现的使用telnet登陆聊天室实例
Jun 17 Python
基于Python的接口测试框架实例
Nov 04 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
Nov 06 Python
基于Python socket的端口扫描程序实例代码
Feb 09 Python
Php多进程实现代码
May 07 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
Sep 02 Python
tensorflow实现逻辑回归模型
Sep 08 Python
Python从单元素字典中获取key和value的实例
Dec 31 Python
python模拟实现斗地主发牌
Jan 07 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
Apr 15 Python
python装饰器实现对异常代码出现进行自动监控的实现方法
Sep 15 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
PHP5/ZendEngine2的改进
2006/10/09 PHP
十天学会php之第八天
2006/10/09 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
php文件包含的几种方式总结
2019/09/19 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
top.location.href 没有权限 解决方法
2008/08/05 Javascript
对new functionName()定义一个函数的理解
2014/05/22 Javascript
Node.js中使用计时器定时执行函数详解
2014/08/15 Javascript
使用Browserify配合jQuery进行编程的超级指南
2015/07/28 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
getElementById().innerHTML与getElementById().value的区别
2016/10/27 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
一个手写的vue放大镜效果
2019/08/09 Javascript
JavaScript实现电灯开关小案例
2020/03/30 Javascript
vue 输入电话号码自动按3-4-4分割功能的实现代码
2020/04/30 Javascript
Vue按时间段查询数据组件使用详解
2020/08/21 Javascript
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
[01:17:47]TNC vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python实现探测socket和web服务示例
2014/03/28 Python
python使用itchat库实现微信机器人(好友聊天、群聊天)
2018/01/04 Python
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
2018/02/21 Python
TensorFlow实现模型评估
2018/09/07 Python
Python实现企业微信机器人每天定时发消息实例
2020/02/25 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
HTML5播放实现rtmp流直播
2020/06/16 HTML / CSS
Reebok俄罗斯官方网上商店:购买锐步运动服装和鞋子
2016/09/26 全球购物
美国最大的高尔夫发球时间预订网站:TeeOff.com
2018/03/28 全球购物
自考生毕业自我鉴定
2013/10/10 职场文书
幼儿园教师岗位职责
2014/03/17 职场文书
歌颂党的演讲稿
2014/09/10 职场文书
卖房授权委托书样本
2014/10/05 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
2016七夕情人节寄语
2015/12/04 职场文书
个人业务学习心得体会
2016/01/25 职场文书
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python