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中的二维数组的操作方法
May 02 Python
python如何获取服务器硬件信息
May 11 Python
Python3.6通过自带的urllib通过get或post方法请求url的实例
May 10 Python
python 自动去除空行的实例
Jul 24 Python
Python爬取qq空间说说的实例代码
Aug 17 Python
Python爬取智联招聘数据分析师岗位相关信息的方法
Aug 13 Python
使用opencv中匹配点对的坐标提取方式
Jun 04 Python
面向新手解析python Beautiful Soup基本用法
Jul 11 Python
Python读写压缩文件的方法
Jul 30 Python
MAC平台基于Python Appium环境搭建过程图解
Aug 13 Python
Python极值整数的边界探讨分析
Sep 15 Python
PyTorch中的torch.cat简单介绍
Mar 17 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
分享下页面关键字抓取components.arrow.com站点代码
2014/01/30 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
2015/02/08 PHP
php使用COPY函数更新配置文件的方法
2015/06/18 PHP
php-msf源码详解
2017/12/25 PHP
javascript学习随笔(使用window和frame)的技巧
2007/03/08 Javascript
使用Javascript实现选择下拉菜单互移并排序
2016/02/23 Javascript
一览画面点击复选框后获取多个id值的方法
2016/05/30 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
2016/12/30 Javascript
vue-cli 默认路由再子路由选中下的选中状态问题及解决代码
2018/09/06 Javascript
VUE兄弟组件传值操作实例分析
2019/10/26 Javascript
让mocha支持ES6模块的方法实现
2020/01/14 Javascript
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
TensorFlow变量管理详解
2018/03/10 Python
python爬取微信公众号文章
2018/08/31 Python
对Python2与Python3中__bool__方法的差异详解
2018/11/01 Python
python实现人工智能Ai抠图功能
2019/09/05 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
如何使用repr调试python程序
2020/02/28 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
python 5个顶级异步框架推荐
2020/09/09 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
python tkinter实现下载进度条及抖音视频去水印原理
2021/02/07 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
多重CSS背景动画实现方法示例
2014/04/04 HTML / CSS
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
TripAdvisor德国:全球领先的旅游网站
2017/12/07 全球购物
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
Delphi CS笔试题
2014/01/04 面试题
2014年机关党建工作总结
2014/11/11 职场文书
大学生个人学年总结
2015/02/15 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
2015年店长个人工作总结
2015/10/23 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
golang中的并发和并行
2021/05/08 Golang
MySQL数据库中varchar类型的数字比较大小的方法
2021/11/17 MySQL
PYTHON InceptionV3模型的复现详解
2022/05/06 Python