第 3 章 容器:列表、元组、字典与集合

Python 内置四大容器,是一切代码的基石:

类型语法有序可变重复典型用途
列表 list[1, 2, 3]✅✅✅顺序数据集合
元组 tuple(1, 2, 3)✅❌✅不可变记录、多返回值
字典 dict{"a": 1}✅(3.7+ 按插入序)✅键不重复键值映射
集合 set{1, 2, 3}❌✅❌去重、成员判断、集合运算

3.1 列表 list

创建与访问

nums = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, [4, 5]]   # 可混合类型、可嵌套
empty = []

nums[0]        # 1
nums[-1]       # 5
nums[1:4]      # [2, 3, 4](切片,同字符串规则)
len(nums)      # 5

增删改

nums.append(6)          # 尾部追加 → [1,2,3,4,5,6]
nums.insert(0, 0)       # 指定位置插入
nums.extend([7, 8])     # 合并另一列表(等价 +=)
nums.pop()              # 弹出末尾并返回
nums.pop(0)             # 弹出指定索引
nums.remove(3)          # 按值删除第一个匹配(不存在则 ValueError)
del nums[0]             # 按索引删除
nums.clear()            # 清空
nums[0] = 99            # 修改

常用操作

nums.sort()                     # 原地排序(升序)
nums.sort(reverse=True)         # 降序
sorted(nums)                    # 返回新列表,不改原列表
words.sort(key=len)             # 按自定义键排序
nums.reverse()                  # 原地反转
nums.index(3)                   # 查值返回索引
nums.count(3)                   # 计数
3 in nums                       # 成员判断
sum(nums); max(nums); min(nums) # 聚合

关键陷阱:列表是引用

a = [1, 2, 3]
b = a               # b 和 a 指向同一个列表!
b.append(4)
print(a)            # [1, 2, 3, 4] —— a 也变了

c = a.copy()        # 浅拷贝(或 a[:] / list(a))
c.append(5)
print(a)            # 不受影响

# 浅拷贝只复制第一层,嵌套对象仍共享:
m = [[1, 2], [3, 4]]
m2 = m.copy()
m2[0][0] = 99
print(m[0][0])      # 99 也变了!嵌套结构请用:
import copy
m3 = copy.deepcopy(m)

3.2 元组 tuple

point = (3, 4)
single = (42,)      # 单元素元组必须带逗号!
not_tuple = (42)    # 这只是数字 42
x, y = point        # 解包
a, *rest = [1, 2, 3, 4]   # a=1, rest=[2,3,4]

元组不可变(不能增删改元素),因此:

  • 可作为字典的键、集合的元素(列表不行);

  • 函数多返回值的本质就是元组:return name, age;

  • 表示结构固定的记录(坐标、RGB 颜色)比列表更语义化、更省内存。

t[0] = 1 会抛 TypeError。注意:元组里的可变对象内容仍可变,如 t = ([1], 2) 时 t[0].append(3) 合法。

3.3 字典 dict

增删改查

user = {"name": "Alice", "age": 25}

user["name"]            # 'Alice'(键不存在抛 KeyError)
user.get("email")       # None(安全访问)
user.get("email", "未填写")   # 带默认值
user["email"] = "a@x.com"     # 新增/修改
del user["age"]               # 删除
user.pop("email")             # 删除并返回值
"name" in user                # 判断键存在(O(1))

遍历

for key in user:                    # 默认遍历键
    print(key)
for value in user.values(): ...
for k, v in user.items():           # 最常用
    print(k, v)

常用方法

d = {"a": 1, "b": 2}
d.update({"c": 3})          # 批量更新
d.setdefault("a", 99)       # 存在则返回现值,不存在才设默认
d | {"d": 4}                # 3.9+ 合并运算符
list(d.keys())              # ['a', 'b', 'c']

键的要求

键必须是可哈希(不可变)类型:str、int、tuple 等可以;list、dict、set 不行。值则任意。

3.4 集合 set

s = {1, 2, 3}
empty = set()          # 空集合必须用 set()!{} 是空字典

s.add(4)
s.discard(10)          # 不存在也不报错(remove 会报错)
s.pop()                # 随机弹出一个
{1, 2, 2, 3}           # {1, 2, 3} —— 自动去重
list(set([1, 2, 2, 3]))# 最快的列表去重法(不保序)

集合运算(数学意义)

a = {1, 2, 3}
b = {2, 3, 4}

a | b    # 并集 {1, 2, 3, 4}    a.union(b)
a & b    # 交集 {2, 3}          a.intersection(b)
a - b    # 差集 {1}             a.difference(b)
a ^ b    # 对称差 {1, 4}        只在其中一个出现
a <= b   # a 是否为 b 的子集

成员判断 x in set 是 O(1)(哈希实现),大列表频繁判断时转成集合能显著提速。

3.5 推导式(Comprehension)—— Pythonic 精髓

# 列表推导式:[表达式 for 变量 in 可迭代 if 条件]
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
matrix_t = [[row[i] for row in matrix] for i in range(3)]   # 可嵌套

# 字典推导式
d = {w: len(w) for w in ["apple", "banana"]}
# {‘apple’: 5, 'banana': 6}

# 集合推导式
uniq_lens = {len(w) for w in ["a", "bb", "cc"]}   # {1, 2}

# 生成器表达式:圆括号,惰性求值,省内存
total = sum(x**2 for x in range(1_000_000))

建议:推导式不超过两层嵌套;更复杂时改用普通 for 循环,可读性优先。

3.6 可变 vs 不可变:贯穿全章的线索

  • 不可变:int、float、str、tuple → 可哈希,能当字典键;

  • 可变:list、dict、set → 不可哈希,作为函数默认参数有著名的坑:

def add(x, items=[]):        # 错误!默认值只创建一次,多次调用共享
    items.append(x)
    return items

def add(x, items=None):      # 正确惯用法
    if items is None:
        items = []
    items.append(x)
    return items

本章小结:记住四种容器的"有序/可变/重复"矩阵;警惕引用共享,需要独立副本时 copy(),嵌套时 deepcopy();推导式要练到顺手;函数默认参数永远别用可变对象。

下一章:控制流——条件、循环与匹配。

Python3 基础知识 / 第 3 章 容器:列表、元组、字典与集合 0 字 0 行 cosolar
2026-09-17T11:10:47.671493703Z 2026-09-17T11:25:53.816619333Z