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之让人欢喜让人忧的迭代
Oct 02 Python
python实现中文输出的两种方法
May 09 Python
使用Python对SQLite数据库操作
Apr 06 Python
利用python打印出菱形、三角形以及矩形的方法实例
Aug 08 Python
Python 中Pickle库的使用详解
Feb 24 Python
django传值给模板, 再用JS接收并进行操作的实例
May 28 Python
pandas 条件搜索返回列表的方法
Oct 30 Python
python 哈希表实现简单python字典代码实例
Sep 27 Python
python 统计文件中的字符串数目示例
Dec 24 Python
python将字典内容写入json文件的实例代码
Aug 12 Python
简述python Scrapy框架
Aug 17 Python
Python  lambda匿名函数和三元运算符
Apr 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
PHP之变量、常量学习笔记
2008/03/27 PHP
PHP中删除变量时unset()和null的区别分析
2011/01/27 PHP
从手册去理解分析PHP session机制
2011/07/17 PHP
smarty内置函数config_load用法实例
2015/01/22 PHP
PHP实现腾讯与百度坐标转换
2017/08/05 PHP
PHP实现的日历功能示例
2018/09/01 PHP
启用OPCache提高PHP程序性能的方法
2019/03/21 PHP
javaScript call 函数的用法说明
2010/04/09 Javascript
JQuery从头学起第三讲
2010/07/06 Javascript
JS正则验证邮箱的格式详细介绍
2013/11/19 Javascript
浅析JavaScript中的隐式类型转换
2013/12/05 Javascript
javascript实现文本域写入字符时限定字数
2014/02/12 Javascript
jQuery中get()方法用法实例
2014/12/27 Javascript
javascript实现的图片切割多块效果实例
2015/05/07 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
vue.js+boostrap项目实践(案例详解)
2016/09/21 Javascript
获取url中用&amp;隔开的参数实例(分享)
2017/05/28 Javascript
ionic3+Angular4实现接口请求及本地json文件读取示例
2017/10/11 Javascript
Angular通过指令动态添加组件问题
2018/07/09 Javascript
BootStrap table实现表格行拖拽效果
2018/12/01 Javascript
详解JavaScript中的强制类型转换
2019/04/15 Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
2019/08/20 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
JavaScript实现轮播图效果
2020/10/30 Javascript
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
Python文件操作类操作实例详解
2014/07/11 Python
Python实现list反转实例汇总
2014/11/11 Python
简单了解Django模板的使用
2017/12/20 Python
Python 打印中文字符的三种方法
2018/08/14 Python
Python拼接字符串的7种方法总结
2018/11/01 Python
python传到前端的数据,双引号被转义的问题
2020/04/03 Python
python中urllib.request和requests的使用及区别详解
2020/05/05 Python
使用python画出逻辑斯蒂映射(logistic map)中的分叉图案例
2020/12/11 Python
Python用requests库爬取返回为空的解决办法
2021/02/21 Python
美国Max仓库:Max Warehouse
2020/05/31 全球购物
中学生运动会通讯稿大全
2014/09/18 职场文书