查看: 212|回复: 3

Python列表与元组核心用法详解:创建、操作、性能对比及实战案例

[复制链接]
发表于 8 小时前 | 显示全部楼层 |阅读模式
在Python编程中,列表(list)和元组(tuple)是最基础也最常用的两种序列类型。二者都用于存储有序元素集合,但特性截然不同:列表可变而元组不可变。掌握它们的设计哲学和操作方法,是写出高效Python代码的关键。本文从创建、访问、修改、遍历到高级技巧(如切片、推导式、解包、深浅拷贝),再到性能对比和常见陷阱,带你系统梳理列表与元组的应用。

---

一、列表:灵活的可变序列

列表通过方括号 [] 定义,元素用逗号分隔,支持任意嵌套。
  1. empty = []
  2. numbers = [1, 2, 3, 4, 5]
  3. mixed = [1, "hello", 3.14, [2, 3]]
  4. range_list = list(range(10))
复制代码

1. 索引与切片
索引从0开始,支持负索引。切片语法 list[start:end:step] 返回子列表。
  1. fruits = ["apple", "banana", "cherry"]
  2. print(fruits[0])  # apple
  3. print(fruits[-1]) # cherry
  4. nums = [0, 1, 2, 3, 4, 5]
  5. print(nums[1:4])  # [1, 2, 3]
  6. print(nums[::2])  # [0, 2, 4]
  7. print(nums[::-1]) # [5,4,3,2,1,0]
复制代码

2. 修改元素
直接通过索引赋值修改。
  1. fruits[1] = "blueberry"
  2. print(fruits) # ['apple', 'blueberry', 'cherry']
复制代码

3. 添加元素
append(x) 追加到末尾;insert(i, x) 在指定位置插入;extend(iterable) 将可迭代对象的所有元素追加。
  1. fruits.append("orange")
  2. fruits.insert(1, "grape")
  3. fruits.extend(["mango", "kiwi"])
  4. print(fruits) # ['apple', 'grape', 'blueberry', 'cherry', 'orange', 'mango', 'kiwi']
复制代码

4. 删除元素
pop(i) 弹出并返回索引i处的元素(默认最后一个);remove(x) 删除第一个值为x的元素;del 按索引删除;clear() 清空列表。
  1. last = fruits.pop()      # 删除并返回 'kiwi'
  2. fruits.remove("grape")   # 删除 'grape'
  3. del fruits[0]            # 删除第一个元素
  4. print(fruits)            # ['blueberry', 'cherry', 'orange', 'mango']
复制代码

5. 查找与统计
index(x) 返回第一个x的索引(不存在则抛出ValueError);count(x) 统计次数;in 检查是否存在。
  1. nums = [1, 2, 3, 2, 4]
  2. print(nums.index(2)) # 1
  3. print(nums.count(2)) # 2
  4. print(3 in nums)     # True
复制代码

6. 排序与反转
sort() 就地排序;sorted() 返回新列表;reverse() 就地反转。
  1. nums = [5, 2, 8, 1]
  2. nums.sort()
  3. print(nums)    # [1, 2, 5, 8]
  4. nums.reverse()
  5. print(nums)    # [8, 5, 2, 1]
复制代码

7. 列表推导式
一种简洁创建列表的方式,通常比循环更快。
  1. squares = [x**2 for x in range(10)]   # [0, 1, 4, 9, ...]
  2. even = [x for x in range(20) if x % 2 == 0]
复制代码

还支持嵌套循环进行扁平化:
  1. matrix = [[1,2,3], [4,5,6], [7,8,9]]
  2. flat = [num for row in matrix for num in row]  # [1,2,3,4,5,6,7,8,9]
复制代码

8. 列表的复制
赋值(new = old)只是引用,不创建副本。浅拷贝可用 copy() 或 old[:];深拷贝需 import copy 后使用 copy.deepcopy()。

---

二、元组:不可变的序列

元组用圆括号 () 定义,一旦创建不可修改。
  1. empty = ()
  2. single = (5,)   # 注意逗号,否则是整数
  3. numbers = (1, 2, 3, 4)
  4. mixed = (1, "hello", 3.14)
  5. tuple_from_list = tuple([1,2,3])
复制代码

索引和切片方式与列表相同。
  1. t = (10, 20, 30, 40)
  2. print(t[1])    # 20
  3. print(t[1:3])  # (20, 30)
复制代码

由于不可变,元组的方法只有 count() 和 index()。若元组中包含可变对象(如列表),该对象内容仍可修改,但元组本身的元素引用不变。

元组的典型用途:
- 保护数据不被意外修改
- 用作字典的键(元组中所有元素必须可哈希)
- 函数返回多个值(自动打包为元组)
- 性能优于列表:创建更快,占用内存更少

---

三、列表与元组的对比

| 特性 | 列表 | 元组 |
|------|------|------|
| 可变性 | 可变(可增删改) | 不可变 |
| 语法 | [] | () |
| 常用方法 | append, extend, insert, remove, pop, sort, reverse, clear | count, index |
| 内存占用 | 较大(支持动态修改) | 较小 |
| 速度 | 略慢 | 略快 |
| 适用场景 | 需要动态修改的数据集 | 固定数据、字典键、函数返回值 |

---

四、序列通用操作

列表和元组都是序列,支持:
- 拼接 +、重复 *
- len()、max()、min()、sum()(仅数值)
- in / not in 成员检查
- for 循环迭代
  1. a = [1, 2]
  2. b = [3, 4]
  3. c = a + b       # [1,2,3,4]
  4. d = a * 3       # [1,2,1,2,1,2]
  5. print(len(c))   # 4
  6. print(2 in a)   # True
复制代码

---

五、高级技巧:解包与星号表达式

将序列解包到多个变量:
  1. point = (10, 20)
  2. x, y = point    # x=10, y=20
  3. first, *rest = [1, 2, 3, 4]   # first=1, rest=[2,3,4]
  4. *head, last = [1, 2, 3, 4]   # head=[1,2,3], last=4
复制代码

在函数调用时可用 * 解包序列作为参数:
  1. args = [1, 2, 3]
  2. print(*args)  # 相当于 print(1, 2, 3)
复制代码

---

六、列表与元组的相互转换

使用 list() 和 tuple() 函数轻松转换。
  1. t = (1, 2, 3)
  2. lst = list(t)   # [1, 2, 3]
  3. t2 = tuple(lst)  # (1, 2, 3)
复制代码

---

七、常见陷阱与最佳实践

1. 列表的浅拷贝问题
只需用 copy() 或切片做的是浅拷贝,内部可变对象仍共享引用。
  1. outer = [[1,2], [3,4]]
  2. inner = outer.copy()
  3. inner[0][0] = 99
  4. print(outer)  # [[99,2], [3,4]]  外部也被改
复制代码

解决:使用 copy.deepcopy()。

2. 元组作为字典键
元组中若包含列表等不可哈希对象,则不能作为键。

3. 不要用列表作为函数默认参数
默认参数在函数定义时仅求值一次,多次调用会共用同一列表,导致数据意外累积。
  1. def add_item(item, lst=[]):
  2.     lst.append(item)
  3.     return lst
  4. print(add_item(1))  # [1]
  5. print(add_item(2))  # [1, 2]  并非预期
复制代码

正确做法:默认值设为 None,函数内部创建新列表。

4. 列表推导式 vs 循环
推导式通常更快更简洁,但连续复杂嵌套会降低可读性,应保持适度。

5. 使用 enumerate() 获取索引
遍历时需同时获取索引和元素,用 enumerate()。
  1. for i, val in enumerate(fruits):
  2.     print(i, val)
复制代码

---

八、实战示例

1. 学生成绩管理
  1. scores = [85, 92, 78, 90, 88]
  2. average = sum(scores) / len(scores)
  3. print(f"平均分: {average:.2f}")
  4. failed = [s for s in scores if s < 60]
  5. print("不及格人数:", len(failed))
复制代码

2. 矩阵转置(使用列表推导式)
  1. matrix = [
  2.     [1, 2, 3],
  3.     [4, 5, 6],
  4.     [7, 8, 9]
  5. ]
  6. transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
  7. print(transposed)  # [[1,4,7], [2,5,8], [3,6,9]]
复制代码

3. 元组作为坐标
  1. points = [(10,20), (30,40), (50,60)]
  2. for x, y in points:
  3.     print(f"x={x}, y={y}")
复制代码

4. 用列表实现栈(后进先出)
  1. stack = []
  2. stack.append("a")
  3. stack.append("b")
  4. stack.append("c")
  5. print(stack.pop())  # c
  6. print(stack.pop())  # b
复制代码

---

列表和元组是Python数据处理的两大基石。列表可变、方法丰富,适合动态数据;元组不可变、轻量、可哈希,适合固定数据和保护性场景。理解它们的区别,并能根据需求灵活选择,是高效编程的重要技能。在此基础上,可以进一步学习其他序列类型(字符串、range)以及 collections 模块中的 deque、namedtuple 等工具,以应对更复杂的数据结构需求。
回复

使用道具 举报

发表于 6 小时前 | 显示全部楼层

Re: Python列表与元组核心用法详解:创建、操作、性能对比及实战案例

楼主总结得很全面!列表和元组的对比表格特别清晰,尤其是性能差异和适用场景那块,对我这种刚入门的很有帮助。想问一下,如果元组里嵌套了列表,修改那个列表的元素时,元组本身的引用确实是没变,但实际数据变了,这种情况有没有什么最佳实践来避免意外修改?比如在需要元组作为字典键的时候,是否一定要保证元组里所有元素都不可变?
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Python列表与元组核心用法详解:创建、操作、性能对比及实战案例

非常详细的总结,收藏了!列表推导式和切片那块写得特别清楚,平时写代码经常用但偶尔会混淆负索引和步长的组合,你这几个例子正好帮我巩固了。另外想请教一个问题:元组做字典键时,如果元组中含有列表这样的可变对象,是不是就不能作为键了?实际开发中一般怎么避免这种情况?
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python列表与元组核心用法详解:创建、操作、性能对比及实战案例

非常感谢楼主如此系统地整理了列表和元组的核心用法,结构清晰,从创建、修改到高级特性都覆盖得很全面。特别是性能对比和深浅拷贝的提醒,对新手避免踩坑很有帮助。 有个小疑问:标题里提到了“实战案例”,但正文在“五、高级”后面就结束了,不知道是不是还有后续内容?比如在实际场景中如何取舍列表和元组、或者结合函数返回多个值时的典型用法。期待楼主能继续补充一些应用实例,这样理解会更深刻。再次感谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-17 18:09 , Processed in 0.043008 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部