当前位置: 首页 > news >正文

Python 的列表 list 和元组 tuple 有啥本质区别?啥时候用谁更合适?

Python 的列表 list 和元组 tuple 有啥本质区别?啥时候用谁更合适?

一句话先看结论

  • 列表 list:能改、能增删,万能“购物车”,适合会变的序列数据。
  • 元组 tuple:不能改,创建后就“锁死”,更省内存、更快读,适合固定不变的数据,比如常量配置、坐标、不可变键等。

为什么会这样?因为 tuple 不允许改动,解释器可做内存和访问优化;list 需要支持增删改,内部会额外预留空间并有更多开销。

语法与不可变性

  • 列表:用方括号 [],可以随时改元素、append、pop。
  • 元组:用圆括号 (),一旦创建不能改(改就报错 TypeError)。

示例:

# 列表:能改
fruits = ["apple", "banana"]
fruits.append("pear")       # OK
fruits[^0] = "orange"        # OK
print(fruits)               # ['orange', 'banana', 'pear']# 元组:不能改
pos = (10, 20, 30)
# pos[^0] = 99               # TypeError: 'tuple' object does not support item assignment
print(pos)                  # (10, 20, 30)

这种“不可变”带来的副作用是:只要里面的元素也都不可变,元组就能当字典的键或放进 set,因为它可哈希;列表不行。

# 元组可做 dict 的键(元素都不可变时)
prices = {("apple", "small"): 3.5, ("apple", "large"): 5.0}
print(prices[("apple", "small")])  # 3.5# 列表做键会报错
# bad = {[1, 2]: "x"}  # TypeError: unhashable type: 'list'

不可变还带来另一个好处:并发里更安全(没人能改它),也更可预测(不担心被无意修改)。

性能与内存:为什么 tuple 往往更省更快(读多改少场景)

  • 内存:相同元素下,tuple 一般比 list 占用更少内存,因为它不需要为“未来的增长”预留空间,也没有可变带来的额外管理开销。
  • 访问/迭代:tuple 往往稍快于 list,尤其“只读访问”场景,因为解释器可针对不可变对象做优化(比如更紧凑的布局、少一点边界检查等)。[2][3][1][5]
  • 但注意:很多日常小规模场景下,这种差距并不大,写业务代码不必为每一次小访问纠结,先选语义更合适的数据结构才是正解。

简单对比(不同机器数值会不同,仅示意):

import sys, timedata_list = [i for i in range(100000)]
data_tuple = tuple(data_list)print("list bytes:", sys.getsizeof(data_list))
print("tuple bytes:", sys.getsizeof(data_tuple))
# 一般会看到 tuple 更小[^1][^7][^10]# 简单迭代耗时对比(多次取平均更客观)
t0 = time.perf_counter()
s = 0
for x in data_list:s += x
t1 = time.perf_counter()s = 0
for x in data_tuple:s += x
t2 = time.perf_counter()print("list iterate:", t1 - t0)
print("tuple iterate:", t2 - t1)
# 通常 tuple 稍快或相近,尤其纯读取场景[^1][^3][^6]

为什么会更省更快?大白话解释:

  • list 是“可扩容的箱子”,需要留富余空位,随时支持 append/insert/pop,因此多点管理成本。
  • tuple 是“密封好的盒子”,大小固定,解释器一次到位分配,更紧凑,拿数据更省事。

另外,tuple 在编译层面还有一些可优化场景,比如“常量折叠”:常量元组可在编译期直接预先构建,少走些指令。

什么时候用 list,什么时候用 tuple?

  • 需要改动(增删改顺序)的序列:用 list,比如收集请求、动态队列、批量构建数据。
  • 固定不变、只读的数据:用 tuple,比如常量配置、固定坐标、RGB 颜色、数据库字段定义等。
  • 需要当 dict 的键或放入 set:用 tuple(且内部元素也要不可变)。
  • 性能敏感、读多写少且数据大:倾向 tuple,省内存、迭代稍快。
  • API 设计想表达“这是只读返回值”:返回 tuple 让调用者一看就知道不可改,更安全。

示例:配置项、坐标等固定数据用 tuple

# 常量配置
ALLOWED_ROLES = ("admin", "editor", "viewer")  # 不希望被修改[^1][^6]# 坐标 / 颜色
origin = (0.0, 0.0)
white = (255, 255, 255)# 作为字典键
edge_weights = {("A", "B"): 1.2,("B", "C"): 0.8,
}  # 键是不可变的元组,语义清晰[^6][^15]

示例:会变的数据用 list

# 任务队列(会变化)
tasks = []
tasks.append("crawl_page")
tasks.append("parse_html")
tasks.pop(0)  # 处理一个
print(tasks)

一些容易踩坑的小点

  • tuple 不可变,但“浅不可变”:如果元组里放的是可变对象,比如列表,那么列表的内容还是能改的;只是不能改“这个位置放的是谁”。
t = (1, [2, 3], 4)
t[^1].append(99)     # 可以,因为改的是内部列表的内容
print(t)            # (1, [2, 3, 99], 4)
# 但 t[^1] = [8, 9] 不行,会 TypeError
  • 想“增加一个元素”的 tuple,本质是创建了一个新 tuple,并不会原地改旧的:
t = (1, 2, 3)
t2 = t + (4,)   # 新建
print(t, "=>", t2)  # (1, 2, 3) => (1, 2, 3, 4)

进阶细节:为什么 tuple 构建/读取可能更快?

  • 不可变意味着解释器知道“大小和内容不变”,可一次性分配、更紧凑地存储,访问时开销更少;同时一些常量元组还能在编译时被折叠,减少运行期开销。
  • list 为了支持动态增长,会“过度分配”预留空位,增删时需要移动或扩容,带来额外成本;但正因如此,它对频繁变动的场景更友好。

小结式指南

  • 优先按语义选型:会变→list;不变→tuple。
  • 想要更省内存、稍快迭代、可当 dict 键/放 set,且数据确实不需要改→tuple。
  • 实际性能别猜,真有需求就用 time/perf_counter 和 sys.getsizeof 做小基准对比再决定。

参考要点基于公开资料的共识:tuple 不可变带来更好的内存紧凑与一定场景下的访问优势;list 提供灵活的增删改,是通用工作马。

http://www.xdnf.cn/news/1276183.html

相关文章:

  • Ubuntu 安装 Kibana
  • 旅行者1号无线电工作频段
  • MyBatisPlus插件原理
  • MVCC和日志
  • 音视频学习(五十一):AAC编码器
  • C4.5算法:增益率(Gain Ratio)
  • 嵌入式第二十四课!!linux应用软件编程与文件操作!!!
  • Rust 实战四 | Traui2+Vue3+Rspack 开发桌面应用:通配符掩码计算器
  • JAVA+AI简化开发操作
  • Java集合中的 LinkedList
  • 每日任务day0810:小小勇者成长记之武器精炼
  • node.js 学习笔记3 HTTP
  • Django @login_required实现登陆认证
  • C/C++内存管理函数模板
  • 小明的魔法地图:迷宫探险智慧(记忆性递归)
  • 【0基础3ds Max】主工具栏介绍(下)
  • [激光原理与应用-223]:机械 - 机加厂加工机械需要2D还是3D图?
  • Python设计模式 - 装饰模式
  • 六、RuoYi-Cloud-Plus OSS文件上传配置
  • QT常用控件三
  • Qt—— 下载、工具介绍以及新建项目
  • 从0开始的中后台管理系统-5(userList页面功能实现)
  • 40.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--初始化网关
  • Pytorch进阶-timm库-00快速开始
  • (三)全栈(部署)
  • 精准计算Word文档页数的PHP类
  • 数据结构-deque(双端队列)和queue(队列)区别
  • 【npm、yarn、pnpm】特点对比,按需选择
  • Java 后端性能优化实战:从 SQL 到 JVM 调优
  • 分布微服务电商订单系统Rust编码开发[上]