第八章:列表与元组

完成本章学习后,你将能够:

  • 掌握列表和元组的所有操作
  • 理解可变与不可变的本质区别
  • 熟练使用列表推导式
  • 掌握切片的高级用法
  • 选择合适的数据结构
# 直接创建
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], [], []]
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]
# 添加元素
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()              # []
# 作为栈(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))
# 直接创建
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)
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)
# 基本解包
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
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)
特性 列表 元组
语法 [1, 2, 3] (1, 2, 3) 或 1, 2, 3
可变性 可变 不可变
性能 稍慢 更快
内存 更多 更少
用途 需要修改的数据 固定数据、字典键
安全 可能被意外修改 更安全
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")

1. 列表操作:实现函数删除列表中所有指定值的元素 2. 矩阵转置:不使用numpy,用列表推导式实现矩阵转置 3. 扁平化:将任意深度的嵌套列表扁平化 4. 数据统计:给定成绩列表,计算平均分、中位数、最高分、最低分 5. 排序算法:实现快速排序或归并排序

本章我们学习了:

  • 列表的创建、索引、切片、方法
  • 元组的特性和解包
  • 命名元组的使用
  • 列表与元组的选择
  • 内存和性能考量

下一章:第九章:字典与集合

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • python/chapter08.txt
  • 最后更改: 2026/04/09 14:26
  • 张叶安