如何在Python 3中使用collections模块
off999 2024-10-01 13:53 30 浏览 0 评论
本文最初发表在DigitalOcean的公共知识库中。我在这里对它进行了一些较小的编辑。
介绍
Python 3有许多内置的数据结构,包括元组、字典和列表。数据结构为我们提供了一种组织和存储数据的方法。collections模块能够帮助我们高效地填充和操作数据结构。
在本教程中,我们将通过collections模块中的三个类来帮助你处理元组、字典和列表。我们将使用namedtuples来创建带有命名字段的元组,使用defaultdict来在字典中精确地分组信息,以及使用deque来高效地向一个类列表对象的每一边添加元素。
在本教程中,我们将主要处理一个鱼类清单,当在虚构的水族箱中添加或删除鱼类时,我们需要修改这些清单。
必备条件
要充分理解本教程,建议你熟悉元组、字典和列表数据类型(包括它们的语法),以及如何从它们中检索数据。你可以查看这些教程,以获得必要的背景信息:
理解Python 3中的元组
理解python3中的字典
Python 3中的理解列表
向元组添加命名字段
Python元组是一个不可变的,或不可改变的,有序的元素序列。元组经常用来表示纵列数据;例如,一个CSV文件中的行数或一个SQL数据库中的行数。一个水族箱可以用一系列元组来记录它的鱼类的库存。
一个单独的鱼类元组:
这个元组由三个字符串元素组成。
虽然在某些方面很有用,但是这个元组并没有清楚地指明它的每个字段代表什么。实际上,元素0是一个名称,元素1是一个物种,元素2是一个饲养箱。
鱼类元组字段说明:
这个表清楚地表明,该元组的三个元素都有明确的含义。
来自collections模块的namedtuple允许你向一个元组的每个元素添加显式名称,以便在你的Python程序中明确这些元素的含义。
让我们使用namedtuple来生成一个类,从而明确地命名鱼类元组的每个元素:
from collections import namedtuple 可以让你的Python程序访问namedtuple工厂函数。namedtuple函数调用会返回一个绑定到名称Fish的类。namedtuple函数有两个参数:我们的新类“Fish”的期望名称和命名元素["name"、"species”、“tank"]的一个列表。
我们可以使用Fish类来表示前面的鱼类元组:
如果我们运行这段代码,我们将看到以下输出:
sammy是使用Fish类进行实例化的。sammy是一个具有三个明确命名元素的元组。
sammy的字段可以通过它们的名称或者一个传统的元组索引来访问:
如果我们运行这两个print调用,我们将看到以下输出:
访问.species会返回与使用[1]访问sammy的第二个元素相同的值。
使用collections模块中的namedtuple可以在维护元组(即它们是不可变的、有序的)的重要属性的同时使你的程序更具可读性。
此外,namedtuple工厂函数还会向Fish实例添加几个额外的方法。
使用._asdict将一个实例转换为字典:
如果我们运行print,你会看到如下输出:
在sammy上调用.asdict将返回一个字典,该字典会将三个字段名称分别映射到它们对应的值。
大于3.8的Python版本输出这一行的方式可能略有不同。例如,你可能会看到一个OrderedDict,而不是这里显示的普通字典。
备注: 在Python中,带有前导下划线的方法通常被认为是“私有的”。但是,namedtuple提供的其他方法(如._asdict、._make、._replace等)是公开的。
在字典中收集数据
在Python字典中收集数据通常是很有用的。collections模块中的defaultdict可以帮助我们快速、简洁地将信息集合到字典中。
defaultdict绝不会引发一个KeyError。如果一个键不存在,defaultdict会插入并返回一个占位符值来代替:
如果我们运行这段代码,我们将看到如下输出:
defaultdict会插入并返回一个占位符值,而不是引发一个KeyError。在本例中,我们将占位符值指定为一个列表。
相比之下,常规字典会在缺失的键上引发一个KeyError:
如果我们运行这段代码,我们将看到如下输出:
当我们试图访问一个不存在的键时,常规字典my_regular_dict会引发一个KeyError。
defaultdict的行为与常规字典不同。defaultdict会不带任何参数调用占位符值来创建一个新对象,而不是在缺失的键上引发一个KeyError。在本例中,是调用list创建一个空列表。
继续我们虚构的水族箱示例,假设我们有一个表示水族箱清单的鱼类元组列表:
水族箱中有三种鱼——它们的名字、种类和饲养箱在这三个元组中都有指出。
我们的目标是按饲养箱组织我们的清单—我们想知道每个饲养箱中存在的鱼的列表。换句话说,我们需要一个能将“tank-a”映射到["Jamie", "Mary"] ,并且将“tank-b”映射到["Jamie"]的字典。
我们可以使用defaultdict来按饲养箱对鱼进行分组:
运行这段代码,我们将看到以下输出:
fish_names_by_tank被声明为一个defaultdict,它默认会插入list而不是引发一个KeyError。由于这保证了fish_names_by_tank中的每个键都将指向一个list,所以我们可以自由地调用.append来将名称添加到每个饲养箱的列表中。
这里,defaultdict帮助你减少了出现未预期的KeyErrors的机会。减少未预期的KeyErrors意味着你可以用更少的行更清晰地编写你的程序。更具体地说,defaultdict习惯用法让你避免了手动地为每个饲养箱实例化一个空列表。
如果没有 defaultdict, for循环体可能看起来更像这样:
使用常规字典(而不是defaultdict)意味着for循环体总是必须检查fish_names_by_tank中给定的tank是否存在。只有在验证了fish_names_by_tank中已经存在tank,或者已经使用一个初始化了tank之后,我们才可以添加鱼类名称。
在填充字典时,defaultdict可以帮助我们减少样板代码,因为它从不引发KeyError。
使用deque有效地将元素添加到集合的任意一侧
Python列表是一个可变的,或可改变的,有序的元素序列。Python可以以常数时间向列表添加内容(列表的长度对添加元素所需的时间没有影响),但是在列表的开头插入可能比较慢——随着列表变大,插入花费的时间也会增加。
就大O符号而言,向列表追加元素操作是一个常数时间O(1)操作。相比之下,在列表的开头插入元素要慢一些,其性能为O(n)。
备注:软件工程师经常使用称为“大O”符号的东西来度量操作的性能。当一个输入的大小对执行一个操作所需的时间没有影响时,我们就可以说该操作以常数时间或 O(1)(“1的大O”)运行。正如你在上面所了解的,Python可以以常数时间性能(也称为O(1))向列表中追加元素。
有时候,输入的大小会直接影响运行一个操作所需的时间。例如,在一个Python列表的开头插入元素时,列表中的元素越多,插入操作的运行速度越慢。大O符号使用字母n表示输入的大小。将项目添加到Python列表的开头以“线性时间”或 O(n)(“n的大O”)运行。
一般来说,O(1)个操作比O(n)个操作更快。
我们可以在一个Python列表的开头插入:
如果我们运行以上代码,我们将看到如下输出:
列表上的.insert(index, object)方法允许我们在favorite_fish_list的开头插入“Alice”。不过,值得注意的是,在一个列表的开头插入项具有O(n)性能。随着favorite_fish_list的长度的增长,在列表的开头插入一个鱼类的时间将成比例地增长,所需时间会越来越长。
collections模块中的deque(发音为“deck”)是一个类似列表的对象,它允许我们以常数时间(O(1))性能在一个序列的开头或末尾插入项。
在一个deque的开头插入一个项:
运行这段代码,我们将看到以下输出:
我们可以使用一个先前存在的元素集合来实例化一个deque,在本例中,该集合是三个最喜欢的鱼类名称的一个列表。调用favorite_fish_deque’s appendleft方法允许我们以O(1)性能在我们集合的开头插入一个项。O(1)性能意味着将一个项添加到 favorite_fish_deque 的开头所花费的时间并不会增加,即使favorite_fish_deque中有数以千计甚至数以百万计的元素。
备注: 尽管deque将条目添加到一个序列的开头比列表更有效,但并不是deque执行所有操作都比列表更高效。例如,访问deque中的一个随机项具有O(n)性能,但是访问列表中的一个随机项具有O(1)性能。当需要快速地从你的集合的任意一侧插入或删除元素时,请使用deque。时间性能的完整比较可以在Python的wiki上找到。
结论
collections模块是Python标准库的一个功能强大的部分,它允许你简洁高效地处理数据。本教程介绍了collections模块提供的三个类,包括namedtuple、 defaultdict和deque。
英文原文:https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html
译者:浣熊君( ????? )
相关推荐
- 笔记本电脑系统修复软件(笔记本电脑程序修复)
-
1、超级兔子2013系统修复软件超级兔子是一款完整的系统维护工具。拥有电脑系统评测、垃圾清理和注册表清理、可疑文件和插件检测、网页防护等功能,同时自带一些实用的系统工具,可清理你大多数的文件、注册表里...
- 联想保修服务包括哪些(联想保修都保修什么)
-
1、保修36个月的硬件包括:CPU、内存。2、保修24个月的硬件包括:主板、显卡、LCD屏、硬盘、电源适配器、键盘、鼠标模块。3、保修12个月的硬件包括:LCD之附件、光驱、DVD、CDR/W、软驱...
- 系统科学大会(中国系统科学学会)
-
2021年各种科学大会的召开时间取决于疫情的发展和国家政策的调整。一些大型的国际科学会议可能会推迟或者采用线上形式进行,以保障参会人员的安全和健康。同时,一些国内的学术会议也会受到疫情的影响,需要推迟...
- win10系统下载的内容在哪(win10下载的软件在哪个文件夹)
-
进入C:\Windows\SoftwareDistribution\Download目录下,通过win10应用商店中下载的安装包都放在此目录下。进入C:\Windows\SoftwareDistrib...
- 下载原版xp系统光盘(xp光盘系统安装教程怎么安装)
-
方法步骤步骤如下:1、首先打开计算机,在电脑光驱上放入XP光盘,启动电脑后不停按F12、F11、Esc等启动热键,在弹出的启动菜单中选择DVD选项,回车。2、进入光盘主菜单,按数字2或点击选项2运行w...
- windows7中文版下载安装(windows7安装包下载)
-
谢邀,如果你戳设置-时间和语言-区域和语言,右边的语言提示“只允许使用一种语言包”,那么你的系统就是家庭中文版。家庭中文版限定系统界面只能使用简体中文显示,其他功能则与普通家庭版没有区别,也可以使用其...
- win7开机按f2怎么重装系统(win7开机按f12怎么重装系统)
-
开机或重启时,在进入Windows前按F2进入BIOS。 ←→移动到第三个好像是BOOT。 然后将EXTENELBOOT选项设置为ENABLE 最后按F5将第一启动项目设置为EXTENEL...
-
- win10驱动管理(win10驱动程序)
-
win10由于联网后会自动安装驱动,如果自动安装驱动没出现问题,即可视为最佳驱动,若出现问题,卸载出问题的驱动,然后去查自己主板型号,在主板供应商官网下载对应驱动即是最佳01Windows10驱动更新调整当前当你插入连接即插即用(Pn...
-
2025-12-29 05:51 off999
- 手机上怎么找qq邮箱登录(用手机怎么找到qq邮箱)
-
入口是“联系人”选项卡。qq邮箱手机在QQ主菜单中选择下方的“联系人”选项卡;3、在“联系人”中选取“公众号”选项卡;4、在公众号中菜单中找到或搜索“QQ邮箱提醒”,点击进入;5、点击“进入邮箱”;6...
- amd显卡控制面板
-
AMD显卡控制面板是用来管理你的AMD显卡的,可以在控制面板中进行设置一些简单的调整,来提升显卡性能和效果。1、先打开AMD控制面板。2、打开“垂直同步(V-SYNC)”功能,可调整细节,改善影像流畅...
- win10老是未响应卡死(window10总是未响应)
-
具体方法:1、如果win10中的应用程序出现不响应的情况,应该是应用程序加载失败了。可以通过重置方法来解决win10应用程序无响应。2、登录win10系统,用管理员身份运行Powershell(可在C...
- usb安装系统步骤(USB安装系统步骤)
-
1.准备一张U盘,将联想官网下载的系统镜像文件复制到U盘中;2.将U盘插入联想S41U电脑,重启电脑,按F12进入BIOS设置,将U盘设置为启动项;3.重启电脑,进入U盘安装界面,按提示操作,完成系统...
- win98安装教程(win98iso怎么安装)
-
如何安装windows98 一、具体安装步骤 备份好重要文件之后,就可以安装windows98了。 第一步:启动安装程序。 用户如果原来已安装了windows95/97/98,现在拟对其进行升...
- 雨林木风win7安装(雨林木风win732位安装教程)
-
安装步骤如下: 1、光盘放入光驱,复制光盘上的win7.gho和安装系统.exe到硬盘非C盘的文件夹;(gho文件名可以是其他名字,后缀为gho,体积最大的就是。) 2、双击安装系统.exe;...
- win10解绑管理员账户(win10管理员账户怎么取消开机密码)
-
要解除Windows10电脑上的管理员权限,您需要进行以下操作:1.打开“控制面板”:右键单击“开始”按钮,然后选择“控制面板”。2.进入“用户账户”:在控制面板中,选择“用户账户”。3.点击...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
