元组不可变,你真的确定吗?有了列表,元组存在的意义又是什么?【一文搞懂】

简介: 元组不可变,你真的确定吗?有了列表,元组存在的意义又是什么?【一文搞懂】

一、前言


学过python的小伙伴都知道,python有一种数据类型叫元组,它与列表很相似!

而元组与列表最让我们熟知的区别就在于元组不可变!

类似下面的代码执行的话会直接报错:

a=(1,2)
a[1]=3
print(a)

报错信息bba6e3151dae481386e8dc9bd594c259.png

但元组真的是不可改变的吗?


下面的这段代码可能会让你心生疑惑

我们定义一个元组它的值为{1,{'key':1}},然后改变它的值:

a = (1, {'key': 1})
a[1]['key'] = 2
print(a)

输出结果:

19bb259113ca49a2b35b6955444114ea.png

6d4d3860c49948d6b784186e29e3b88a.jpg


这结果不是改变了吗!!!

那为啥都说元组不可变!!!


二、分析


其实说元组不可变实际上没有错,它指的是元组里元素的内存地址不可改变

我们把改变前和改变后的元素id打印出来,会发现他们是一样的

a = (1, {'key': 1})
print('改变之前的元素id', id(a[1]))
a[1]['key'] = 2
print('改变之后的元素id', id(a[1]))

输出结果

58f9b2a697934057855217bf63564fbc.png


至于为什么修改了元素的值,元素的内存地址未改变。是因为该元素的类型是dict,而dict又是一个可变类型,仅仅改变里面的值的话不会改变其内存地址(详情可参考:python不可变类型和可变类型讲解)


所以在元组中修改它的值是可以的。


三、为什么有了列表还要有不可修改的元组呢?

这里从三个方面做解答

1.元组性能优于列表


元组占用的空间比列表少


我们仅仅定义了6个相同的元素,分配的空间大小就相差了快1倍!

a = [1, 2, 3, 4, 5, 6]
print('列表的空间大小为:', a.__sizeof__())
b = (1, 2, 3, 4, 5, 6)
print('元组的空间大小为:', b.__sizeof__())

输出结果

5c444df35a3d4bed9617fbaec2617a10.png


另外,在Python的垃圾回收机制下,如果一些变量不再使用了,Python会回收它们所占用的内存并返还给操作系统,以便让其他变量或其他应用使用这部分内存。


但是对于一些静态变量,比如元组,当它不被使用并且占用空间不大时,Python 会暂时缓存这部分内存。这样,下次我们再创建同样大小的元组时,Python 就可以不用再向操作系统发出请求,去寻找内存,而是可以直接分配之前缓存的内存空间,这样就能大大加快程序的运行速度!


2.元组可以作为字典key而列表不行


输入下面的代码执行的话会直接报错!


a = [1, 2]
b={a:1}

输出结果

dba3ca0766e040faafd7b51cced3c9ff.png


而如果用元组作为字典的key的话则不会报错!

a = (1, 2)
b={a:1}
print(b)


输出结果


b2fd88242b5545de81dc816f549daf27.png

准确的说,所有不可变类型都可以,而类似list 的可变类型则不可以!!


3.工厂函数


这里就要提到python的一个工厂函数具名元组(namedtuple)


具名元组是 python 标准库 collections 中的工厂函数。它接受两个参数,第一个参数表示类的名称,第二个参数是类的字段名。后者可以是可迭代对象,也可以是空格隔开的字符串。然后,我们通过一串参数的形式将参数传递到构造函数中。这样,我们既可以通过字段名访问元素,也可以用索引访问元素。


只讲具名元组,可能不太好理解。如果称之为带字段名的记录,你可能就清楚了。


现在我们创建一个人员的基础信息类People


它有三个属性:姓名name、性别sex、年龄age


现在创建一个姓名叫张三,22岁的小伙儿,再打印出他的信息

from collections import namedtuple
People = namedtuple('People', 'name sex age')
# 存放在对应字段里的数据要以一串参数的形式传入到构造函数中
person = People('张三', '男', 22)
print(person)
print(person.name)  # 通过字段名获取一个字段的值
print(person._fields)  # 通过fields来获取它有哪些属性


输出结果


3b14348cd2a84cb9862feb024f0a6d19.png


还可以直接将具名元组转化为orderdict(在上述代码末尾加入下列代码)


person_dict = person._asdict()
print(person_dict)


输出结果

06f2bccf1409477b9a6ce426a610cac5.png


四、总结


元组是一种很强大的可以当作记录来用的数据类型,这才是他存在的价值和意义所在!

只是作为一个不可变的列表更被大家所熟知而已。

目录
相关文章
|
人工智能 监控 安全
什么是网络即服务 (NaaS)?
我们经常听到云计算领域中有IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务),但是你知道吗?在网络领域也有一种术语叫做NaaS(网络即服务),本文瑞哥就带大家揭开NaaS的神秘面纱,让我们直接开始!
4913 0
什么是网络即服务 (NaaS)?
|
Java Apache 数据格式
httpclient 解决 connection reset 问题
  httpclient 解决 connection reset 问题   错误如下:   java.net.SocketException: Connection reset at java.
9485 0
|
8月前
|
人工智能 机器人 API
OpenClaw(Clawdbot)阿里云无影云电脑秒级部署+LINE集成:从0到1搭建AI聊天机器人保姆级教程
OpenClaw(曾用名Clawdbot)是一款轻量化、可扩展的开源AI智能体执行框架,支持自然语言指令驱动、多模型灵活切换与全场景任务自动化。阿里云无影云电脑凭借**零环境配置、一键部署、7×24小时稳定运行**的特性,成为新手部署OpenClaw的最优选择,无需复杂本地环境搭建,即可快速搭建云端AI服务。接入LINE后,可在LINE应用中直接与OpenClaw交互,实现AI对话、技能调用、任务执行等功能,打造专属LINE AI聊天机器人。
621 1
|
5月前
|
存储 人工智能 安全
2026 云手机双雄盘点:安卓、iOS 谁更适合刷手游日常?
云手机无“全能解”,安卓党重功能多开,iOS党求安全稳定。2026年口碑双雄:桃心云(安卓旗舰,8核+16G,AI托管/无限多开,高性价比);瓜瓜云(原生iOS真机集群,账号零关联、72小时稳挂机)。按需选择,避坑省钱。
|
6月前
|
人工智能 JSON 运维
2026 生产级 AI Agent 自动化:零重型框架,彻底解决多步任务不稳定难题
本文提出“文件即状态”轻量架构,用5个文件实现AI Agent多步任务的稳定执行,无需LangGraph等重型框架。支持断点续跑、幂等重试、跨Agent协同,个人开发者7天即可落地生产级自动化。(239字)
|
7月前
|
JavaScript 算法 数据库
制造业报价困局:BOM自动解析与智能报价核算破局
JBoltAI推出智能报价系统,以BOM自动解析与智能核算技术破解制造业报价难题:秒级解析复杂物料清单,精准匹配工艺参数,标准化核算加工费及杂项成本,提升报价效率与准确性,助力企业降本增效、赢得订单。(239字)
294 5
|
8月前
|
网络协议 安全 测试技术
api工具apifox、apipost选择
Apifox 与 Apipost 各有侧重:Apifox 是面向中大型团队的一站式 API 全生命周期管理平台,强在协作、自动化与流程闭环;Apipost 则以多协议调试(gRPC/TCP/WebSocket)、离线能力及小团队友好性见长。选型需结合团队规模、协议需求与安全要求。(239字)
744 2
|
8月前
|
数据采集 运维 网络协议
IPv4 和 IPv6 归属地查询有差异?运维必看的高效查询技巧
作为运维工程师,IPv4/IPv6归属地查询日益关键。本文剖析二者在类型识别、格式规范、字段维度及数据库覆盖率等核心差异,提供标准化IP处理代码与高可用查询方案,助您提升查询准确率与效率。(239字)
570 1
|
10月前
|
人工智能
不是工程师,也不是老板:AI智能体来了时代最稀缺的职业,叫“领航员
智能体时代已至,执行者正被系统取代。真正稀缺的不是会用AI的人,而是能定义目标、设计流程、掌控结果的“领航员”。从操作AI到指挥AI,未来价值取决于你站在哪一层。
|
10月前
|
人工智能 JavaScript 搜索推荐
AI Agent MCP 源代码部署Deployment 获得子域名Live URL的0-1教程
本文介绍如何将AI Agent或MCP服务部署上线,获取免费二级域名(如*.aiagenta2z.com),并在ChatGPT、Claude等客户端中直接使用。涵盖代码准备、入口命令配置、GitHub部署及调试全流程,支持Python/Node.js项目,助力开发者快速实现服务托管与集成。