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

Python 列表(List)与元组(Tuple)详解

Python 列表(List)与元组(Tuple)详解

核心区别一句话总结:列表可变,元组不可变。这一差异决定了它们各自的应用场景和性能特性。

在 Python 中,列表(List)和元组(Tuple)是两种常用的序列类型,用于存储多个元素。它们的核心区别在于可变性:列表是可变的(元素可修改),而元组是不可变的(元素一旦创建就无法修改)。本文将详细介绍两者的用法、区别及适用场景。

列表(List):可变的序列

列表是 Python 中最灵活的序列类型,使用方括号[]定义,元素之间用逗号分隔,支持添加、删除、修改等操作。

基本定义与创建
# 空列表empty_list=[]# 包含不同类型元素的列表(Python 列表支持异构元素)mixed_list=[1,"apple",3.14,True]# 嵌套列表(列表中包含列表)nested_list=[1,[2,3],[4,[5,6]]]
访问元素

通过索引(下标)访问元素,索引从0开始,支持负数索引(从末尾计数,-1表示最后一个元素)。

fruits=["apple","banana","cherry","date"]# 访问单个元素print(fruits[0])# 输出:apple(第一个元素)print(fruits[-1])# 输出:date(最后一个元素)# 分片(切片):获取子列表,语法为 [start:end:step],左闭右开print(fruits[1:3])# 输出:['banana', 'cherry'](索引1到2的元素)print(fruits[:2])# 输出:['apple', 'banana'](从开头到索引1)print(fruits[2:])# 输出:['cherry', 'date'](从索引2到结尾)print(fruits[::2])# 输出:['apple', 'cherry'](步长为2,间隔一个元素)# 复制列表(创建副本,修改副本不影响原列表)fruits_copy=fruits[:]# 获取元素对应索引index=fruits.index(target)
修改元素

列表是可变的,可直接通过索引修改元素:

numbers=[1,2,3,4]numbers[1]=20# 将索引1的元素改为20print(numbers)# 输出:[1, 20, 3, 4]
添加元素
  • append(x):在列表末尾添加元素x
  • insert(index, x):在指定索引index处插入元素x
  • extend(iterable):将可迭代对象(如列表、元组)的元素添加到末尾。
colors=["red","green"]colors.append("blue")# 末尾添加print(colors)# 输出:['red', 'green', 'blue']colors.insert(1,"yellow")# 索引1处插入print(colors)# 输出:['red', 'yellow', 'green', 'blue']colors.extend(["purple","orange"])# 批量添加print(colors)# 输出:['red', 'yellow', 'green', 'blue', 'purple', 'orange']
删除元素
  • del list[index]:删除指定索引的元素。
  • list.remove(x):删除第一个值为x的元素(若不存在则报错)。
  • list.pop(index):删除并返回指定索引的元素(默认删除最后一个)。
languages=["Python","Java","C++","Python"]dellanguages[1]# 删除索引1的元素print(languages)# 输出:['Python', 'C++', 'Python']languages.remove("Python")# 删除第一个"Python"print(languages)# 输出:['C++', 'Python']popped=languages.pop()# 删除最后一个元素print(popped)# 输出:Pythonprint(languages)# 输出:['C++']
常用操作
  • len(list):获取列表长度。
  • list.count(x):统计元素x出现的次数。
  • list.sort():对列表排序(原地修改)。
  • list.reverse():反转列表(原地修改)。
nums=[3,1,4,1,5]print(len(nums))# 输出:5(长度)print(nums.count(1))# 输出:2(1出现的次数)nums.sort()# 排序print(nums)# 输出:[1, 1, 3, 4, 5]nums.reverse()# 反转print(nums)# 输出:[5, 4, 3, 1, 1]

元组(Tuple):不可变的序列

元组使用小括号()定义,元素不可修改,适合存储不需要变更的数据。

基本定义与创建
# 普通元组tup1=(1,2,3,4)# 单元素元组(必须加逗号,否则会被视为普通括号)single_tuple=(5,)# 空元组empty_tuple=()# 省略括号的元组(Python 允许)implicit_tuple=10,20,30# 嵌套元组nested_tuple=(1,(2,3),(4,5,6))
访问元素

元组的访问方式与列表完全相同,支持索引和分片:

animals=("cat","dog","bird","fish")print(animals[2])# 输出:bird(索引2的元素)print(animals[-2])# 输出:bird(倒数第二个元素)print(animals[1:3])# 输出:('dog', 'bird')(分片)
不可变性说明

元组的元素一旦创建就无法修改,试图修改会报错:

tup=(1,2,3)tup[0]=10# 报错:TypeError: 'tuple' object does not support item assignment

注意:如果元组中包含可变元素(如列表),则该元素内部可以修改:

mutable_in_tuple=(1,[2,3],4)mutable_in_tuple[1][0]=20# 元组中的列表元素可修改print(mutable_in_tuple)# 输出:(1, [20, 3], 4)
元组的常用操作

虽然元组不可变,但支持以下操作:

  • len(tuple):获取长度。
  • tuple.count(x):统计元素x出现的次数。
  • tuple.index(x):返回元素x第一次出现的索引。
  • 元组拼接(创建新元组,原元组不变)。
t1=(1,2,3)t2=(4,5)print(len(t1))# 输出:3print(t1.count(2))# 输出:1print(t1.index(3))# 输出:2t3=t1+t2# 拼接元组(创建新元组)print(t3)# 输出:(1, 2, 3, 4, 5)
函数返回多参数

严格来说,一个函数只能返回一个值,但是如果这个值是一个元组,效果就会和返回多个值一样了

def get_name_and_age(): name = "Alice" age = 25 return name, age # 这会返回一个元组 (('Alice', 25),) name, age = get_name_and_age() print(name) print(age)

列表与元组的核心区别

特性列表(List)元组(Tuple)
定义符号方括号[]小括号()(可省略)
可变性可变(可修改、添加、删除元素)不可变(元素创建后无法修改)
性能略低(需维护可变结构)更高(内存占用少,访问速度快)
适用场景元素需动态修改(如数据收集)元素固定不变(如配置、常量)
哈希性不可哈希(不能作为字典的键)可哈希(可作为字典的键)

如何选择:列表还是元组?

  • 用列表:当需要添加、删除或修改元素时(如动态收集用户输入、存储可变更的数据集)。
  • 用元组:当数据一旦创建就不需要修改时(如存储配置项、函数返回多个值、作为字典的键)。

示例:函数返回多个值(本质是返回元组)

defget_user_info():name="Alice"age=30returnname,age# 隐式返回元组user=get_user_info()print(user)# 输出:('Alice', 30)(元组)name,age=user# 解包(元组特有的便捷操作)print(name,age)# 输出:Alice 30

查看类型

如果不确定值是什么类型,可以使用type来进行判断

>>>type(6)<class'int'>>>>type('H')<class'str'>>>>fruits=["apple","banana","cherry","date"]>>>type(fruits)<class'list'>>>>tup1=(1,2,3,4)>>>type(tup1)<class'tuple'>>>>

快速选型指南

场景推荐类型
动态收集用户输入列表 ✅
存储配置常量(如颜色RGB值)元组 ✅
作为字典的键元组 ✅
函数返回多个值元组 ✅
需要排序、反转、增删操作列表 ✅
数据量大且只读(提高性能)元组 ✅
与其他开发者协作(明确数据不可变意图)元组 ✅

常见陷阱与最佳实践

🚨 陷阱 1:使用可变对象作为默认参数
# ❌ 错误示例(默认参数是可变对象)defadd_item(item,my_list=[]):my_list.append(item)returnmy_listprint(add_item(1))# [1]print(add_item(2))# [1, 2] ← 意外!多次调用共享了同一个列表# ✅ 正确做法defadd_item(item,my_list=None):ifmy_listisNone:my_list=[]my_list.append(item)returnmy_listprint(add_item(1))# [1]print(add_item(2))# [2]
🚨 陷阱 2:浅拷贝 vs 深拷贝
importcopy nested=[[1,2],[3,4]]# 浅拷贝:只复制外层,内层列表仍共享shallow=nested[:]shallow[0][0]=99print(nested)# [[99, 2], [3, 4]] ← 原列表也被修改!# 深拷贝:完全独立deep=copy.deepcopy(nested)deep[0][0]=999print(nested)# [[99, 2], [3, 4]] ← 原列表不受影响
🚨 陷阱 3:列表乘法与引用
# ❌ 错误:创建了多个指向同一列表的引用matrix=[[0]*3]*3# [[0, 0, 0], [0, 0, 0], [0, 0, 0]]matrix[0][0]=1print(matrix)# [[1, 0, 0], [1, 0, 0], [1, 0, 0]] ← 意外!# ✅ 正确:使用列表推导式matrix=[[0]*3for_inrange(3)]matrix[0][0]=1print(matrix)# [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
最佳实践总结
  1. 明确意图:数据不需要修改时,优先使用元组(自文档化)
  2. 性能敏感:大量只读数据使用元组,内存占用更小
  3. 类型提示:使用类型注解明确预期类型
fromtypingimportList,Tupledefprocess_data(items:List[int])->Tuple[int,int]:returnmin(items),max(items)# 返回元组
  1. 字典键:需要复合键时,使用元组而非列表
  2. 解包友好:元组常用于固定数量的返回值

总结

场景选择原因
数据会变化列表支持动态操作
数据固定不变元组性能更好,可哈希,意图明确
需要作为字典键元组列表不可哈希
函数返回多个值元组Python 默认行为,解包方便
数据量大且只读元组内存占用更小,访问更快

记住一句话默认用元组,需要修改时用列表。这会让你的代码更安全、更高效、更易读。

http://www.jsqmd.com/news/958567/

相关文章:

  • RT-Thread串口DMA接收不定长数据,我用消息队列这么搞(附完整代码)
  • LIS2DW12在智能手环中的低功耗配置实战:如何将功耗降到1µA以下?
  • EB Garamond 12:如何为你的设计项目注入古典优雅气质
  • 小米手表表盘设计终极指南:零代码打造个性化智能穿戴界面
  • 2026江苏高职单招长期班优质机构推荐榜
  • SM内最多容纳多少线程?
  • WSL 2 + Docker 本地全栈开发环境配置指南
  • 驾驭未来:一文读懂智能驾驶中的深度学习模型
  • 2026新手开店靠谱加盟公司TOP5:开店攻略/开店选址/开店项目/新手开店/精品开店/莱啦开店加盟/集合店开店/选择指南 - 优质品牌商家
  • BiliSum开源:B站YouTube视频一键转笔记+思维导图,数据纯本地
  • Chinese-Medical-DIALOGUE-Data:构建中文医疗AI对话系统的终极实践指南
  • 微信小程序计算机毕设之微信小程序的博物馆文创商城系统的设计与实现基于springboot+微信小程序的博物馆文创系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 从充电头到高速传输:手把手教你根据项目需求选对Type-C引脚方案(附PCB布局建议)
  • 音乐解锁神器:5分钟打破平台加密,让付费音乐真正属于你!
  • Java+MySQL+Mybatis+Junit4实现学生信息管理系统
  • 为何VMware上云之路充满挑战?
  • 递归函数的设计方法
  • 1分钟教你如何AI生图
  • 2026年养殖池防渗膜市场新观察:陵县源头厂家的核心价值与选择逻辑 - 2026年企业资讯
  • M4Markets整体表现账户稳吗?
  • 费县实操为主的家电清洗培训学校 行业入门标准与培训流程科普
  • Spring Boot:整合Quartz集群部署指南
  • 动态加密路由系统:策略引擎实战
  • 5分钟部署Office全家桶:零代码自动化安装完整指南
  • Gemma 4 12B本地部署避坑:OMLX后缀、4bit/8bit选择与gemma4_unified报错修复
  • yt-dlp:16万 Star 的命令行音视频下载器
  • 从SATA到PCIe 4.0:你的硬盘接口和协议是怎么‘拖后腿’的?聊聊真实场景下的速度瓶颈
  • 【课程设计/毕业设计】基于springboot+微信小程序的博物馆文创系统的设计与实现文创商品展示与售卖、文化背景讲解【附源码、数据库、万字文档】
  • 2026四川市政管网服务企业排行:四川龙基万市政工程有限公司联系、成都化粪池清理电话号码、成都厂区化粪池清理哪家好选择指南 - 优质品牌商家
  • 别再死磕单体了!从EAI到ServiceMesh,聊聊那些年我们踩过的架构‘坑’