python中的deque详解

文章目录

  • 摘要
  • 示例1:基本使用
  • 示例2:使用maxlen限制队列长度
  • 示例3:使用deque实现滑动窗口算法
  • 示例 4: 使用 deque 实现旋转数组
  • 示例 5: 使用 deque 实现最大/最小栈
  • 示例 6: 使用 deque 实现广度优先搜索(BFS)

摘要

deque(双端队列)是Python标准库collections模块中的一个类,它支持从两端快速添加和删除元素。deque为固定大小或者可变大小的队列提供了线程安全的实现,并且它比使用列表(list)来实现相同的功能更为高效。
在这里插入图片描述

deque的主要特点和操作包括:

  • 快速从两端添加和删除元素deque在两端添加和删除元素的时间复杂度都是O(1),而列表在列表头部添加或删除元素的时间复杂度是O(n)。
  • 线程安全deque的实例可以在多线程环境中安全使用,而不需要额外的锁定。
  • 可选的最大长度:可以通过maxlen参数来限制deque的最大长度。当deque已满时,添加新元素会导致最早添加的元素被自动移除。

下面是deque的一些详细示例:

示例1:基本使用

from collections import deque

# 创建一个空的deque
d = deque()

# 从右侧添加元素
d.append('a')
d.append('b')
print(d)  # 输出:deque(['a', 'b'])

# 从左侧添加元素
d.appendleft('c')
print(d)  # 输出:deque(['c', 'a', 'b'])

# 从右侧移除元素
right_item = d.pop()
print(right_item)  # 输出:'b'
print(d)  # 输出:deque(['c', 'a'])

# 从左侧移除元素
left_item = d.popleft()
print(left_item)  # 输出:'c'
print(d)  # 输出:deque(['a'])

示例2:使用maxlen限制队列长度

from collections import deque

# 创建一个最大长度为3的deque
d = deque(maxlen=3)

# 添加元素
d.append('a')
d.append('b')
d.append('c')
print(d)  # 输出:deque(['a', 'b', 'c'], maxlen=3)

# 继续添加元素,最早添加的元素'a'将被移除
d.append('d')
print(d)  # 输出:deque(['b', 'c', 'd'], maxlen=3)

# 尝试从左侧添加元素,同样会移除最早添加的元素
d.appendleft('e')
print(d)  # 输出:deque(['e', 'c', 'd'], maxlen=3)

示例3:使用deque实现滑动窗口算法

滑动窗口算法常用于数组或列表的子序列问题,如寻找最大/最小子序列和。

from collections import deque

def max_sliding_window(nums, k):
    # 使用deque保存窗口中的最大值索引
    window = deque()
    result = []

    for i in range(len(nums)):
        # 如果deque不为空且当前元素大于deque尾部元素对应的值,则移除尾部元素
        while window and nums[window[-1]] <= nums[i]:
            window.pop()
        # 添加当前元素的索引到deque
        window.append(i)
        # 当窗口大小达到k时,开始记录窗口内的最大值,并尝试移动窗口左边界
        if i >= k - 1:
            result.append(nums[window[0]])  # window[0]是当前窗口内最大值的索引
            # 如果deque头部的索引已经不在当前窗口内,则移除头部索引
            if window[0] <= i - k:
                window.popleft()

    return result

nums = [1, 3, -1, -3, 5, 3, 6, 7]
k = 3
print(max_sliding_window(nums, k))  # 输出:[3, 3, 5, 5, 6, 7]

在这个例子中,deque用于存储当前窗口内元素值的索引,通过维护一个递减的索引队列,我们可以快速找到窗口内的最大值。当窗口向右滑动时,我们更新队列并记录每个窗口的最大值。

在Python中,collections.deque 是一个非常实用的双向队列实现,它可以高效地在队列两端添加或移除元素。以下是一些使用 deque 的示例:

示例 4: 使用 deque 实现旋转数组

from collections import deque

def rotate_array(nums, k):
    dq = deque(nums)
    dq.rotate(-k)  # 逆时针旋转 k 位,如果是顺时针旋转则直接写 k
    return list(dq)

nums = [1, 2, 3, 4, 5, 6, 7]
k = 3
rotated_nums = rotate_array(nums, k)
print(rotated_nums)  # 输出: [5, 6, 7, 1, 2, 3, 4]

示例 5: 使用 deque 实现最大/最小栈

from collections import deque

class MaxStack:
    def __init__(self):
        self.stack = deque()
        self.max_stack = deque()

    def push(self, x):
        self.stack.append(x)
        if not self.max_stack or x >= self.max_stack[-1]:
            self.max_stack.append(x)

    def pop(self):
        if self.stack:
            if self.stack[-1] == self.max_stack[-1]:
                self.max_stack.pop()
            return self.stack.pop()
        return None

    def top(self):
        return self.stack[-1] if self.stack else None

    def getMax(self):
        return self.max_stack[-1] if self.max_stack else None

# 使用示例
max_stack = MaxStack()
max_stack.push(5)
max_stack.push(7)
max_stack.push(1)
max_stack.push(5)
print(max_stack.getMax())  # 输出: 7
max_stack.pop()
print(max_stack.top())  # 输出: 5
print(max_stack.getMax())  # 输出: 7

在这个例子中,MaxStack 类使用两个 deque:一个用于存储栈的元素,另一个用于存储当前栈中的最大值。这样,我们可以在常数时间内获取栈顶的最大值。
在这里插入图片描述

示例 6: 使用 deque 实现广度优先搜索(BFS)

在图的遍历中,deque 常用于实现广度优先搜索(BFS)。

from collections import deque

def bfs(graph, root):
    visited = set()
    queue = deque([root])

    while queue:
        vertex = queue.popleft()
        print(vertex, end=" ")

        for neighbour in graph[vertex]:
            if neighbour not in visited:
                visited.add(neighbour)
                queue.append(neighbour)

# 图的邻接表表示
graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F'],
    'D': [],
    'E': ['F'],
    'F': []
}

bfs(graph, 'A')  # 输出: A B C D E F

在上面的例子中,我们使用 deque 作为队列来存储待访问的节点,实现了图的广度优先搜索。

这些示例展示了 deque 在不同场景下的应用,从基本的队列操作到更复杂的算法实现。deque 的灵活性和高效性使得它成为处理序列数据的强大工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/502696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣56. 合并区间

Problem: 56. 合并区间 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.将数组按内部的一维数组的第一项按从小到大的顺序排序&#xff1b; 2.创建二维结果数组merged&#xff0c;并将排序后的数组中的第一个一维度数组存入到merged中&#xff1b; 3.从后面的一…

理解游戏服务器架构-部署架构

目录 前言 我所理解的服务器架构 什么是否部署架构 部署架构的职责 进程业务职责 网络链接及通讯方式 与客户端的连接方式 服务器之间连接关系 数据落地以及一致性 数据库的选择 数据访问三级缓存 数据分片 读写分离 分布式数据处理 负载均衡 热更新 配置更新 …

express实现用户登录和注册接口

目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求&#xff0c;express本身并不提供直接操作数据库的能力&#xff0c;需要借助第三方库来操作数据库&#xff0c;本篇讲解一下软件开发…

【Java】LinkedList模拟实现

目录 整体框架IMyLinkedList接口IndexNotLegalException异常类MyLinkedList类成员变量(节点信息)addFirst(头插)addLast(尾插)在指定位置插入数据判断是否存在移除第一个相等的节点移除所有相等的节点链表的长度打印链表释放回收链表 整体框架 IMyLinkedList接口 这个接口用来…

2006-2023年2月各地级市城投债详细数据

2006-2023.2各地级市城投债详细数据 1、时间&#xff1a;2006-2023.2 2、来源&#xff1a;深圳证券交易所和上海证券交易所官网、人民银行、证券监督管理委员会等金融监管机构等官网 3、指标&#xff1a;省份、城市、证券代码、证券简称、债券简称、证券全称、债券初始面值单…

C语言使用STM32开发板手搓高端家居洗衣机

目录 概要 成品效果 背景概述 1.开发环境 2.主要传感器。 技术细节 1. 用户如何知道选择了何种功能 2.启动后如何进行洗衣 3.如何将洗衣机状态上传至服务器并通过APP查看 4.洗衣过程、可燃气检测、OLED屏显示、服务器通信如何并发进行 小结 概要 本文章主要是讲解如…

使用pdf表单域填充pdf内容

需要引用如下包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-core</artifactId><version>8.0.3</version><type>pom</type></dependency>1、预先准备一个pdf模板&#xff0c;并在指定位置添加…

创建一个vue3 + ts + vite 项目

vite 官网&#xff1a; https://cn.vitejs.dev/guide/ 兼容性注意 Vite 需要 Node.js 版本 18&#xff0c;20。然而&#xff0c;有些模板需要依赖更高的 Node 版本才能正常运行&#xff0c;当你的包管理器发出警告时&#xff0c;请注意升级你的 Node 版本。 安装项目 1. 使用n…

政安晨:【Keras机器学习实践要点】(五)—— 通过子类化创建新层和模型

目录 介绍 安装 层级&#xff1a;状态&#xff08;权重&#xff09;与某些计算的组合 层可以有不可训练的重量 最佳实践&#xff1a;推迟权重的创建&#xff0c;直到输入的形状已知。 层可以递归组合 后端不可知层和特定后端层 add_loss()方法 可以选择在您的层上启用…

【DETR系列目标检测算法代码精讲】01 DETR算法01 DETR算法框架和网络结构介绍

为什么要有DETR 总所周知&#xff0c;传统的目标检测算法非常依赖于anchor和nms等手工设计操作&#xff0c;非常费时费力&#xff0c;自然而然的就产生了取消这些操作的想法。但是我们首先需要思考的是&#xff0c;为什么我们需要anchor和nms&#xff1f; 因为我们是没有指定…

3D汽车模型线上三维互动展示提供视觉盛宴

VR全景虚拟看车软件正在引领汽车展览行业迈向一个全新的时代&#xff0c;它不仅颠覆了传统展览的局限&#xff0c;还为参展者提供了前所未有的高效、便捷和互动体验。借助于尖端的vr虚拟现实技术、逼真的web3d开发、先进的云计算能力以及强大的大数据处理&#xff0c;这一在线展…

Docker Swarm安装部署应用

一、Docker Swarm核心概念 1、什么是Docker Swarm GitHub地址 Docker Swarm 是 Docker 官方推出的容器集群管理工具&#xff0c;基于 Go 语言实现。使用它可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机&#xff0c;快速打造一套容器云平台。 Docker Swarm 是生产…

Java线程池工作原理浅析

为什么要用线程池&#xff1f; 1、线程属于稀缺资源&#xff0c;它的创建会消耗大量系统资源 2、线程频繁地销毁&#xff0c;会频繁地触发GC机制&#xff0c;使系统性能降低 3、多线程并发执行缺乏统一的管理与监控 线程池的使用 线程池的创建使用可通过Executors类来完成…

【网站项目】泉文化管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Vue2(十二):Vuex环境搭建、Vuex工作原理、几个配置项、多组件共享数据、Vuex模块化

一、Vuex 1.概念 专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff08;use引入&#xff09;&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读&#xff0f;写&#xff09;&#xff0c;也是一种组件间通信的方式&…

String,StringBuffer,StringBuilder 的区别【大白话Java面试题】

String&#xff0c;StringBuffer&#xff0c;StringBuilder 的区别【大白话Java面试题】 大白话回答 1、可变/不可变类 String是不可变类。他被被final修饰&#xff0c;所以每一次的创建修改删除都要重新分配内存创建新的对象。 StringBuilder和StringBuffer是可变类&#xff…

Linux部署Sonarqube+Gogs+Jenkins(一)

Linux部署SonarqubeGogsJenkins 一、1.Linux安装JDK11环境1. 本地进行上传2. 进入到/usr/java目录&#xff0c;并且进行解压3. 配置文件/etc/profile&#xff0c;配置环境变量4.让对应的配置文件生效5. 验证 二、Linux安装Python环境三、Linux安装Jenkins环境1、/usr目录下创建…

ssm框架笔记-maven

html是骨头 css使皮肤 js是你能做的动作 MAVEN 依赖管理&#xff1a;1.声明dependenciys标签 2.maven search3。 版本号提取 3.$引用 3.2依赖传递和冲突 依赖传递指的是当一个模块或库 A 依赖于另一个模块或库 B&#xff0c;而 B 又依赖于模块或库 C&#xff0c;那么 A 会间…

ADT 创建表,并用ABAP往里面插数据

参考&#xff1a;Create Table Persistence and Generate Data | SAP Tutorials 4、Replace your code with following: CLASS zcl_generate_travel_data_xxx DEFINITIONPUBLICFINALCREATE PUBLIC .PUBLIC SECTION.INTERFACES if_oo_adt_classrun.PROTECTED SECTION.PRIVATE S…

基于SSM医院病历管理系统

基于SSM医院病历管理系统的设计与实现 摘要 病历管理系统是医院管理系统的重要组成,在计算机技术快速发展之前&#xff0c;病人或者医生如果想记录并查看自己的健康信息是非常麻烦的&#xff0c;因为在以往病人的健康信息通常只保存在自己的病历卡或者就诊报告中&#xff0c;…