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爬取读者并制作成PDF
Mar 10 Python
python基于右递归解决八皇后问题的方法
May 25 Python
Python设计模式之MVC模式简单示例
Jan 10 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
Mar 02 Python
Python实现中一次读取多个值的方法
Apr 22 Python
Python 修改列表中的元素方法
Jun 26 Python
python实现从pdf文件中提取文本,并自动翻译的方法
Nov 28 Python
python  文件的基本操作 菜中菜功能的实例代码
Jul 17 Python
python多线程实现代码(模拟银行服务操作流程)
Jan 13 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
python压包的概念及实例详解
Feb 17 Python
教你怎么用Python实现GIF动图的提取及合成
Jun 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
Laravel实现ApiToken认证请求
2019/10/14 PHP
javascript编程起步(第三课)
2007/02/27 Javascript
js将long日期格式转换为标准日期格式实现思路
2013/04/07 Javascript
javascript定义变量时带var与不带var的区别分析
2015/01/12 Javascript
js无法获取到html标签的属性的解决方法
2016/07/26 Javascript
JavaScript实现鼠标点击导航栏变色特效
2017/02/08 Javascript
jQuery中绑定事件bind() on() live() one()的异同
2017/02/23 Javascript
Javascript创建类和对象详解
2017/05/31 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
Vue 源码分析之 Observer实现过程
2018/03/29 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
webpack4 + react 搭建多页面应用示例
2018/08/03 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
js实现省级联动(数据结构优化)
2020/07/17 Javascript
js实现滑动进度条效果
2020/08/21 Javascript
JavaScript实现滚动加载更多
2020/12/27 Javascript
[36:20]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.17
2020/12/18 DOTA
pandas数据分组和聚合操作方法
2018/04/11 Python
Python Requests库基本用法示例
2018/08/20 Python
python三大神器之fabric使用教程
2019/06/10 Python
3行Python代码实现图像照片抠图和换底色的方法
2019/10/10 Python
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
TripAdvisor日本:全球领先的旅游网站
2019/02/14 全球购物
英国购买威士忌网站:Master of Malt
2019/09/26 全球购物
入党自我鉴定范文
2013/10/04 职场文书
数控技术专业推荐信
2013/11/01 职场文书
小学体育课教学反思
2016/02/16 职场文书
工作汇报材料难写?方法都在这里了!
2019/07/01 职场文书
Python利用folium实现地图可视化
2021/05/23 Python
Springboot配置suffix指定mvc视图的后缀方法
2021/07/03 Java/Android
MySQL中一条update语句是如何执行的
2022/03/16 MySQL
Win11筛选键导致键盘失灵怎么解决? Win11关闭筛选键的技巧
2022/04/08 数码科技
SQL Server中的逻辑函数介绍
2022/05/25 SQL Server
SpringBoot Http远程调用的方法
2022/08/14 Java/Android