显示页面讨论过去修订反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== 第八章:列表与元组 ====== ===== 本章目标 ===== 完成本章学习后,你将能够: * 掌握列表和元组的所有操作 * 理解可变与不可变的本质区别 * 熟练使用列表推导式 * 掌握切片的高级用法 * 选择合适的数据结构 ===== 列表(List) ===== ==== 列表创建 ==== <code python> # 直接创建 empty = [] numbers = [1, 2, 3, 4, 5] mixed = [1, "hello", 3.14, True, None] nested = [[1, 2], [3, 4], [5, 6]] # 使用list()函数 chars = list("hello") # ['h', 'e', 'l', 'l', 'o'] nums = list(range(5)) # [0, 1, 2, 3, 4] # 列表乘法 zeros = [0] * 10 # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 注意:乘法对于可变对象的陷阱 lists = [[]] * 3 lists[0].append(1) print(lists) # [[1], [1], [1]],三个引用同一个列表! # 正确做法 lists = [[] for _ in range(3)] lists[0].append(1) print(lists) # [[1], [], []] </code> ==== 列表索引与切片 ==== <code python> items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 索引 print(items[0]) # 0 print(items[-1]) # 9(最后一个) print(items[-2]) # 8(倒数第二个) # 切片 [start:stop:step] print(items[2:5]) # [2, 3, 4] print(items[:3]) # [0, 1, 2] print(items[7:]) # [7, 8, 9] print(items[:]) # 副本 print(items[::2]) # [0, 2, 4, 6, 8](偶数索引) print(items[1::2]) # [1, 3, 5, 7, 9](奇数索引) print(items[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0](反转) # 切片赋值 items[2:5] = [20, 30] # 可以用不同长度的列表替换 print(items) # [0, 1, 20, 30, 5, 6, 7, 8, 9] # 删除切片 del items[2:4] print(items) # [0, 1, 5, 6, 7, 8, 9] </code> ==== 列表方法 ==== <code python> # 添加元素 lst = [1, 2, 3] lst.append(4) # [1, 2, 3, 4],在末尾添加 lst.insert(0, 0) # [0, 1, 2, 3, 4],在指定位置插入 lst.extend([5, 6]) # [0, 1, 2, 3, 4, 5, 6],扩展列表 # 删除元素 lst.remove(3) # 删除第一个值为3的元素 popped = lst.pop() # 删除并返回最后一个元素(6) popped = lst.pop(0) # 删除并返回指定索引的元素(0) del lst[0] # 删除指定索引 # 查找 lst = [1, 2, 3, 2, 4] print(lst.index(2)) # 1,第一个2的位置 print(lst.index(2, 2)) # 3,从索引2开始找 print(lst.count(2)) # 2,2出现的次数 print(5 in lst) # False # 排序 lst = [3, 1, 4, 1, 5, 9, 2, 6] lst.sort() # 原地排序 lst.sort(reverse=True) # 降序 lst.sort(key=lambda x: -x) # 自定义排序 # 复制 lst = [1, 2, [3, 4]] copy1 = lst.copy() # 浅拷贝 copy2 = lst[:] # 浅拷贝 copy3 = list(lst) # 浅拷贝 import copy deep = copy.deepcopy(lst) # 深拷贝 # 反转 lst.reverse() # 原地反转 reversed_lst = lst[::-1] # 返回新列表 # 清空 lst.clear() # [] </code> ==== 列表作为栈和队列 ==== <code python> # 作为栈(LIFO - 后进先出) stack = [] stack.append(1) # 入栈 stack.append(2) stack.append(3) top = stack[-1] # 查看栈顶 item = stack.pop() # 出栈,item = 3 # 作为队列(FIFO - 先进先出),但效率低 queue = [] queue.append(1) # 入队 queue.append(2) item = queue.pop(0) # 出队,item = 1(O(n)操作,效率低!) # 高效队列使用collections.deque from collections import deque d = deque() d.append(1) # 右端添加 d.appendleft(0) # 左端添加 d.pop() # 右端移除 d.popleft() # 左端移除(O(1)) </code> ===== 元组(Tuple) ===== ==== 元组创建 ==== <code python> # 直接创建 empty = () single = (1,) # 注意:必须有逗号! not_tuple = (1) # 这只是整数1 numbers = (1, 2, 3) # 括号可以省略 numbers = 1, 2, 3 a, b = 1, 2 # 元组解包 # 使用tuple()函数 chars = tuple("hello") # ('h', 'e', 'l', 'l', 'o') nums = tuple([1, 2, 3]) # (1, 2, 3) </code> ==== 元组不可变性 ==== <code python> t = (1, 2, 3) # t[0] = 10 # TypeError: 'tuple' object does not support item assignment # 但元组中的可变元素可以修改 t = ([1, 2], [3, 4]) t[0].append(3) # 可以! print(t) # ([1, 2, 3], [3, 4]) # 重新赋值变量,不是修改元组 t = (1, 2, 3) t = t + (4, 5) # 创建新元组 print(t) # (1, 2, 3, 4, 5) </code> ==== 元组解包 ==== <code python> # 基本解包 coordinates = (3, 4) x, y = coordinates print(x, y) # 3 4 # 扩展解包(Python 3+) first, *rest = [1, 2, 3, 4, 5] print(first) # 1 print(rest) # [2, 3, 4, 5] *beginning, last = [1, 2, 3, 4, 5] print(beginning) # [1, 2, 3, 4] print(last) # 5 first, *middle, last = [1, 2, 3, 4, 5] print(middle) # [2, 3, 4] # 忽略值 x, _, y = (1, 2, 3) # _常用于表示不关心的值 x, *_, y = (1, 2, 3, 4, 5) # _接收[2, 3, 4] # 交换变量 a, b = 1, 2 a, b = b, a # 元组解包实现交换 print(a, b) # 2 1 </code> ==== 命名元组(Named Tuple)==== <code python> from collections import namedtuple # 定义 Point = namedtuple('Point', ['x', 'y']) Person = namedtuple('Person', 'name age city') # 也可以用空格分隔的字符串 # 创建实例 p = Point(3, 4) alice = Person('Alice', 25, 'NYC') # 访问 print(p.x, p.y) # 3 4 print(p[0], p[1]) # 3 4(也支持索引) print(alice.name) # Alice # 不可变 # p.x = 10 # AttributeError # 转换为字典 print(alice._asdict()) # 替换字段(创建新实例) alice2 = alice._replace(age=26) </code> ===== 列表 vs 元组 ===== | 特性 | 列表 | 元组 | | 语法 | [1, 2, 3] | (1, 2, 3) 或 1, 2, 3 | | 可变性 | 可变 | 不可变 | | 性能 | 稍慢 | 更快 | | 内存 | 更多 | 更少 | | 用途 | 需要修改的数据 | 固定数据、字典键 | | 安全 | 可能被意外修改 | 更安全 | <code python> import sys import timeit # 内存对比 lst = [1, 2, 3, 4, 5] t = (1, 2, 3, 4, 5) print(f"列表: {sys.getsizeof(lst)} bytes") print(f"元组: {sys.getsizeof(t)} bytes") # 性能对比 list_time = timeit.timeit("[1, 2, 3, 4, 5]", number=1000000) tuple_time = timeit.timeit("(1, 2, 3, 4, 5)", number=1000000) print(f"列表创建: {list_time:.4f}s") print(f"元组创建: {tuple_time:.4f}s") </code> ===== 本章练习 ===== 1. **列表操作**:实现函数删除列表中所有指定值的元素 2. **矩阵转置**:不使用numpy,用列表推导式实现矩阵转置 3. **扁平化**:将任意深度的嵌套列表扁平化 4. **数据统计**:给定成绩列表,计算平均分、中位数、最高分、最低分 5. **排序算法**:实现快速排序或归并排序 ===== 本章小结 ===== 本章我们学习了: * 列表的创建、索引、切片、方法 * 元组的特性和解包 * 命名元组的使用 * 列表与元组的选择 * 内存和性能考量 下一章:[[python_course:chapter09|第九章:字典与集合]] 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 python/chapter08.txt 最后更改: 2026/04/09 14:26由 张叶安 登录