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的线程来解决生产者消费问题的示例
Apr 02 Python
Python 正则表达式实现计算器功能
Apr 29 Python
解决Python运行文件出现out of memory框的问题
Dec 03 Python
Python3实现取图片中特定的像素替换指定的颜色示例
Jan 24 Python
详解Python字典的操作
Mar 04 Python
Django 创建新App及其常用命令的实现方法
Aug 04 Python
python 进程的几种创建方式详解
Aug 29 Python
15行Python代码实现免费发送手机短信推送消息功能
Feb 27 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
Aug 02 Python
Python爬虫设置Cookie解决网站拦截并爬取蚂蚁短租的问题
Feb 22 Python
Python基于Opencv识别两张相似图片
Apr 25 Python
Python3 如何开启自带http服务
May 18 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 Mysql日期和时间函数集合
2007/11/16 PHP
提高PHP编程效率的53个要点(经验小结)
2010/09/04 PHP
控制PHP的输出:缓存并压缩动态页面
2013/06/11 PHP
解析mysql 表中的碎片产生原因以及清理
2013/06/22 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
2019/06/14 PHP
laravel admin实现分类树/模型树的示例代码
2020/06/10 PHP
php 中序列化和json使用介绍
2013/07/08 Javascript
JS控制图片等比例缩放的示例代码
2013/12/24 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
JavaScript ParseFloat()方法
2015/12/18 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
2016/04/07 Javascript
解析JavaScript实现DDoS攻击原理与保护措施
2016/12/26 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
jQuery实现页面倒计时并刷新效果
2017/03/13 Javascript
javascript实现最长公共子序列实例代码
2018/02/05 Javascript
Webpack中雪碧图插件使用详解
2018/05/25 Javascript
浅谈vue项目,访问路径#号的问题
2020/08/14 Javascript
[01:03:38]2014 DOTA2国际邀请赛中国区预选赛5.21 CNB VS CIS
2014/05/22 DOTA
[01:20]DOTA2 齐天大圣至宝动态展示
2016/12/13 DOTA
Python简单进程锁代码实例
2015/04/27 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
Python实现对一个函数应用多个装饰器的方法示例
2018/02/09 Python
python XlsxWriter模块创建aexcel表格的实例讲解
2018/05/03 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
2019/01/03 Python
Python常见数字运算操作实例小结
2019/03/22 Python
django-rest-swagger对API接口注释的方法
2019/08/29 Python
python属于跨平台语言码
2020/06/09 Python
东南亚地区最大的购物网站Lazada新加坡站点:Lazada.sg
2016/07/17 全球购物
JACK & JONES荷兰官网:男士服装和鞋子
2021/03/07 全球购物
幼儿园毕业教师感言
2014/02/21 职场文书
员工入职担保书范文
2014/04/01 职场文书
大学生社会实践评语
2014/04/25 职场文书
中学生旷课检讨书2篇
2014/10/09 职场文书
《爱的教育》读书心得
2014/11/08 职场文书
尼克胡哲观后感
2015/06/08 职场文书
react合成事件与原生事件的相关理解
2021/05/13 Javascript