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使用多线程不断刷新网页的方法
Mar 31 Python
解读Django框架中的低层次缓存API
Jul 24 Python
在Mac OS系统上安装Python的Pillow库的教程
Nov 20 Python
python Django模板的使用方法
Jan 14 Python
浅谈python jieba分词模块的基本用法
Nov 09 Python
使用Python进行AES加密和解密的示例代码
Feb 02 Python
基于Python List的赋值方法
Jun 23 Python
Python字典循环添加一键多值的用法实例
Jan 20 Python
使用Python控制摄像头拍照并发邮件
Apr 23 Python
Pycharm远程调试原理及具体配置详解
Aug 08 Python
python输入错误后删除的方法
Oct 12 Python
Python高级特性——详解多维数组切片(Slice)
Nov 26 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.MVC的模板标签系统(三)
2006/09/05 PHP
PHP递归遍历多维数组实现无限分类的方法
2016/05/06 PHP
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
JQuery 选择和过滤方法代码总结
2010/11/19 Javascript
JSuggest自动匹配下拉框使用方法(示例代码)
2013/12/27 Javascript
seaJs的模块定义和模块加载浅析
2014/06/06 Javascript
jQuery中Ajax的load方法详解
2015/01/14 Javascript
nodejs中的fiber(纤程)库详解
2015/03/24 NodeJs
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
2016/01/22 Javascript
JavaScript中数组的各种操作的总结(必看篇)
2017/02/13 Javascript
Bootstrap BootstrapDialog使用详解
2017/02/17 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
VUE DOM加载后执行自定义事件的方法
2018/09/07 Javascript
vue遍历生成的输入框 绑定及修改值示例
2019/10/30 Javascript
Javascript Web Worker使用过程解析
2020/03/16 Javascript
[01:11]回顾历届DOTA2国际邀请赛中国区预选赛
2017/06/26 DOTA
[45:50]完美世界DOTA2联赛PWL S3 CPG vs Forest 第二场 12.16
2020/12/17 DOTA
Python 异常处理的实例详解
2017/09/11 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
python的等深分箱实例
2019/11/22 Python
python 成功引入包但无法正常调用的解决
2020/03/09 Python
Python数组拼接np.concatenate实现过程
2020/04/18 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
python 利用panda 实现列联表(交叉表)
2021/02/06 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
美体小铺奥地利官方网站:The Body Shop奥地利
2019/04/11 全球购物
印刷工程专业应届生求职信
2013/09/29 职场文书
小学生新学期寄语
2014/01/19 职场文书
教师评语大全
2014/04/28 职场文书
教师工作态度自我评价
2015/03/05 职场文书
反腐倡廉影片观后感
2015/06/08 职场文书
《陶罐和铁罐》教学反思
2016/03/03 职场文书
jQuery ajax - getScript() 方法和getJSON方法
2021/05/14 jQuery
nginx.conf配置文件结构小结
2022/04/08 Servers
vue实现登陆页面开发实践
2022/05/30 Vue.js