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

Python基础教程(五)list和tuple:深度剖析Python列表与元组的终极对决

在Python的世界里,list(列表)和tuple(元组)这对"孪生兄弟"看似相似,实则暗藏玄机!本文将带您深入它们的底层实现,揭示性能差异,并解锁高级使用技巧。


核心差异:可变性(Mutability)之战

特性

List(列表)

Tuple(元组)

可变性

可变(Mutable)

不可变(Immutable)

语法

方括号 [ ]

圆括号 ( )

内存分配

动态分配(Over-allocate)

固定分配(Fixed)

哈希支持

❌ 不可哈希

✅ 可哈希

典型用途

动态数据集

固定配置项

# 可变性演示
my_list = [1, 2, 3]
my_list[0] = 99  # ✅ 成功修改 → [99, 2, 3]my_tuple = (1, 2, 3)
my_tuple[0] = 99  # ❌ 抛出TypeError

性能对决:速度与内存的较量

内存占用测试(10万元素):

import sys
list_mem = sys.getsizeof([0]*100000)  # ≈ 824456字节
tuple_mem = sys.getsizeof(tuple([0]*100000))  # ≈ 800056字节

元组比列表节省约 3% 内存空间

创建速度测试(百万次迭代):

import timeit
list_time = timeit.timeit('x=[1,2,3,4,5]', number=1000000)
tuple_time = timeit.timeit('x=(1,2,3,4,5)', number=1000000)

元组创建速度比列表快 2-3倍


底层黑科技:CPython的源码揭秘

列表的弹性结构(Python/Include/listobject.h):

typedef struct {PyObject_VAR_HEADPyObject **ob_item;  // 指针数组Py_ssize_t allocated; // 预分配空间
} PyListObject;

列表采用动态数组策略,预分配额外空间(如:新增元素时扩容1.125倍)

元组的静态结构(Python/Include/tupleobject.h):

typedef struct {PyObject_VAR_HEADPyObject *ob_item[1]; // 固定大小数组
} PyTupleObject;

元组在创建时即固定内存布局,无额外空间开销


高级技巧:突破常规用法

1. 元组解包(Tuple Unpacking)

# 多重赋值
x, y, z = (10, 20, 30)# 函数返回多个值
def get_coordinates():return 3.5, 8.2
lat, lon = get_coordinates()

2. 命名元组(Namedtuple)

from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
bob = Person(name="Bob", age=30)
print(bob.name)  # 比普通元组更易读

3. 列表的切片魔法

nums = [1, 2, 3, 4, 5]
nums[1:3] = [20, 30, 40]  # 替换子序列 → [1, 20, 30, 40, 4, 5]
nums[::2] = [0]*len(nums[::2])  # 替换奇数位 → [0, 20, 0, 40, 0, 5]

经典陷阱:90%开发者踩过的坑

1. 可变元素的元组陷阱

t = ([1, 2], 3)
t[0].append(3)  # ✅ 虽然元组不可变,但内部列表可变 → ([1,2,3], 3)

2. 列表复制的浅拷贝问题

a = [[1,2], [3,4]]
b = a.copy() 
b[0][0] = 99  # 修改嵌套列表会影响原列表!
print(a)  # [[99,2], [3,4]]

3. 误用空元组

empty = ()  # 正确空元组
not_empty = (10)  # ❌ 实际是整数10 
correct = (10,)   # ✅ 单元素元组需要逗号

最佳实践:何时用谁?

使用List的场景:

  • 需要动态增删元素的数据集
  • 实现栈(append/pop)或队列(collections.deque更优)
  • 需要原地修改的数据集合
  • 构建多维数据结构(如:列表的列表)

使用Tuple的场景:

  • 字典键值(因可哈希性)
  • 函数参数和返回值
  • 常量配置项(如颜色RGB值)
  • 数据库查询结果集
  • 多线程共享数据(利用不可变性)

性能优化终极指南

  1. 数据初始化优化
# 快速创建大型不可变序列
large_data = tuple(range(1000000))  # 比列表快30%
  1. 循环内避免列表重复扩容
# 低效写法
result = []
for i in range(10000):result += [i]  # 每次循环触发扩容检查# 高效写法
result = [None]*10000  # 预分配
for i in range(10000):result[i] = i
  1. 内存视图妙用
arr = bytearray(b'Python')
mem_view = memoryview(arr)
print(mem_view[2:5].tobytes())  # b'tho' 无需复制数据

"列表是工作马,元组是精密的瑞士军刀。" —— Python核心开发者Raymond Hettinger

掌握列表与元组的本质区别,不仅能写出更高效的代码,更能深入理解Python的设计哲学。在Python优化之路上,这对"孪生兄弟"将助你游刃有余!

http://www.dtcms.com/a/323143.html

相关文章:

  • PHP-单引号和双引号(通俗易懂讲解版)
  • 卫星遥感与AI大模型
  • JS逆向实战案例之----【通姆】252个webpack模块自吐
  • NFS 挂载失败** 问题(`mount: wrong fs type`),以下是详细的排查步骤和解决方案
  • 20250809在WIN10下使用diskpart命令格式化TF卡【卡刷荣品PRO-RK3566的核心板】
  • 云渲染的未来已来:渲酷云如何重新定义数字内容生产效率
  • SimBA算法实现过程
  • 39.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--调整发布脚本
  • 利用SymPy与SciPy高效求解参数化方程组的数值解
  • [激光原理与应用-207]:光学器件 - 光纤种子源激光器常用元器件
  • 9-DS18B20-verilog驱动
  • Zabbix自动注册:轻松实现大规模监控
  • [LLM 应用评估] 评估指标 | 评估协调器 | 测试集生成组件
  • 【MATLAB例程】基于UKF的IMM例程,模型使用CA(匀加速)和CT(协调转弯)双模型,二维环境下的轨迹定位。附代码下载链接
  • Python映射合并技术:多源数据集成的高级策略与工程实践
  • Python如何合并两个Excel文件
  • Qt 综述:从基础到一般应用
  • 【第十章】高阶函数揭秘:map、filter、reduce 玩转数据流
  • 数据结构与算法:树状数组
  • BGP笔记
  • [FOC电机控制]霍尔传感器于角度问题
  • 基于IPD体系的研发项目范围管理
  • 畅捷通T+删除维护用户时提示,请先删除消息规则设置
  • 把大模型“关进冰箱”——基于知识蒸馏 + 动态量化的小型化实战笔记
  • 谷歌警告云存储桶劫持攻击
  • 【Python办公】基于Flask的数据看板大屏开发实战
  • 微雪电子发布工业级ESP32-S3-POE工控板:8路隔离IO,双核240MHz赋能AIoT,一根网线解决供电与通信,工业物联网迎来高性价比控制新选择
  • UCMT部分复现
  • sql基础版(DQL)
  • 【股票数据API接口18】如何获取次新股池数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据