Python collections中的双向队列deque简单介绍详解

前言

在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是队列可以设定固定长度,实现先入先出。 那么,如在计算移动平均的时候可以使用,很快捷方便。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python Deque 模块使用详解

    创建Deque序列: from collections import deque d = deque() Deque提供了类似list的操作方法: d = deque() d.append('1') d.append('2') d.append('3') len(d) d[0] d[-1] 输出结果: 3 '1' '3' 两端都使用pop: d = deque('12345') len(d) d.popleft() d.pop() d 输出结果: 5 '1' '5' deque(['2', '3

  • 详解Python的collections模块中的deque双端队列结构

    deque 是 double-ended queue的缩写,类似于 list,不过提供了在两端插入和删除的操作. appendleft 在列表左侧插入 popleft 弹出列表左侧的值 extendleft 在左侧扩展 例如: queue = deque() # append values to wait for processing queue.appendleft("first") queue.appendleft("second") queue.appendl

  • Python collections中的双向队列deque简单介绍详解

    前言 在python神书<Python+Cookbook>中有这么一段话:在队列两端插入或删除元素时间复杂度都是 O(1) ,而在列表的开头插入或删除元素的时间复杂度为 O(N). 于是就想验证下. 简单使用 基本代码 from collections import deque q = deque(maxlen=4)#有固定长度的双向队列 qq = deque() #无固定长度 print(dir(q))#看看有哪些可用方法或属性 结果: ['__add__', '__bool__', '__

  • Python 中 Virtualenv 和 pip 的简单用法详解

    本文介绍了Python 中 Virtualenv 和 pip 的简单用法详解,分享给大家,具体如下: 0X00 安装环境 我们在 Python 开发和学习过程中需要用到各种库,然后在各个不同的项目和作品里可能用的版本还不一样,正因为有这种问题的存在才催生了virtualenv的诞生.virtualenv 可以在电脑上创建一个虚拟环境,可以针对每一个项目创建一个虚拟环境,这样就不用担心各个不同的项目用不同版本的库的时候出现的冲突了. 下面的内容只适用于 Linux/OSX,未经 Windows 环

  • python 函数中的内置函数及用法详解

    今天来介绍一下Python解释器包含的一系列的内置函数,下面表格按字母顺序列出了内置函数: 下面就一一介绍一下内置函数的用法: 1.abs() 返回一个数值的绝对值,可以是整数或浮点数等. print(abs(-18)) print(abs(0.15)) result: 18 0.15 2.all(iterable) 如果iterable的所有元素不为0.''.False或者iterable为空,all(iterable)返回True,否则返回False. print(all(['a','b',

  • C语言中带头双向循环链表基本操作的实现详解

    目录 一.概念与结构 二.基本操作的实现 1.创建结点 2.初始化链表 3.打印链表 4.尾插 5.尾删 6.头插 7.头删 8.查找某个数并返回其指针 9.在某个位置之前插入 10.删除某个位置 11.判断链表是否为空 12.计算链表中有效值的个数 13.销毁链表 三.测试代码 一.概念与结构 无头单向非循环链表结构简单,一般不会单独用来存数据.实际中更多的是作为其他数据结构的子结构,如哈希桶.图的邻接表等等.而带头双向循环链表的结构较为复杂,一般用在单独存储数据.实际中使用的链表数据结构,都

  • Python对象中__del__方法起作用的条件详解

    对象的__del__是对象在被gc消除回收的时候起作用的一个方法,它的执行一般也就意味着对象不能够继续引用. 示范代码如下: class Demo: def __del__(self): print("calling __del__") obj = Demo() del obj 程序执行结果如下: grey@DESKTOP-3T80NPQ:/mnt/e/01_workspace/02_programme_language/03_python/03_OOP/2017/08$python

  • 对python PLT中的image和skimage处理图片方法详解

    用PLT比较轻量级,用opencv是比较重量级 import numpy as np from PIL import Image if __name__ == '__main__': image_file = '/Users/mac/Documents/学习文档/机器学习/5.Package/son.png' height = 100 #假定写入图片的高度是100 img = Image.open(image_file) img_width, img_height = img.size #获取i

  • python编程中简洁优雅的推导式示例详解

    目录 1. 列表推导式 增加条件语句 多重循环 更多用法 2. 字典推导式 3. 集合推导式 4. 元组推导式 Python语言有一种独特的推导式语法,相当于语法糖的存在,可以帮助你在某些场合写出较为精简酷炫的代码.但没有它,也不会有太多影响.Python语言有几种不同类型的推导式. 1. 列表推导式 列表推导式是一种快速生成列表的方式.其形式是用方括号括起来的一段语句,如下例子所示: lis = [x * x for x in range(1, 10)] print(lis) 输出 [1, 4

  • Python函数中参数是传递值还是引用详解

    在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(arg) a = 1 foo(a) # 输出:2 print(a) # 输出:1 看了代码段1的同学可能会说参数是值传递. 代码段2: def bar(args): args.append(1) b = [] print(b)# 输出:[] print(id(b)) # 输出:4324106952 b

  • Python之Scrapy爬虫框架安装及简单使用详解

    题记:早已听闻python爬虫框架的大名.近些天学习了下其中的Scrapy爬虫框架,将自己理解的跟大家分享.有表述不当之处,望大神们斧正. 一.初窥Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了页面抓取(更确切来说,网络抓取)所设计的, 也可以应用在获取API所返回的数据(例如Amazon Associates Web Services) 或者通用的网络爬虫. 本文档将通过介绍Sc

  • python程序中的线程操作 concurrent模块使用详解

    一.concurrent模块的介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 ProcessPoolExecutor:进程池,提供异步调用 ProcessPoolExecutor 和 ThreadPoolExecutor:两者都实现相同的接口,该接口由抽象Executor类定义. 二.基本方法 submit(fn, *args, **kwargs) :异步提交任务 map(func, *iterables,

随机推荐