摘要:本文系统梳理了 Python 容器的概念、分类与使用好处,深入讲解了列表、元组、集合、字典以及 collections 模块中的 deque、namedtuple、Counter、defaultdict、OrderedDict 等高级容器,并总结了增删改查、遍历、切片、推导式等核心操作,最后给出了容器选择与学习建议,帮助读者全面掌握 Python 容器知识体系。

目录

1. 什么是容器

2. 容器的分类

3. 使用容器的好处

4. 常用容器详解

4.1 列表(list)

4.2 元组(tuple)

4.3 集合(set)

4.4 字典(dict)

4.5 其他高级容器(collections 模块)

deque(双端队列)

namedtuple(命名元组)

Counter(计数器)

defaultdict(默认值字典)

OrderedDict(有序字典)

5. 容器的常见操作

5.1 增删改查(CRUD 操作)

5.2 遍历与迭代

5.3 切片操作(序列类型)

5.4 推导式(Comprehension)

5.5 排序与反转

5.6 成员检查

5.7 内置函数

5.8 容器之间的转换

6. 总结


1. 什么是容器

在 Python 中,容器(Container)是一种用于存放和管理多个元素的数据结构。它就像现实生活中的"容器"一样——一个箱子可以装很多物品,一个文件夹可以放很多文件。Python 容器允许我们将多个值组织在一起,方便统一管理和操作。

从技术角度看,容器是实现了特定协议(如 __contains____iter____len__ 等方法)的对象,它们能够容纳其他对象,并提供访问、遍历和修改这些对象的能力。

简单理解:变量好比一个"停车位",只能放一辆车;而容器好比一个"停车场",可以同时停放多辆车,并且能对它们进行统一管理。

2. 容器的分类

Python 中的容器可以从多个维度进行分类,最常见的是按数据组织方式分为以下三大类:

分类 包含类型 核心特征
序列类型 列表(list)、元组(tuple)、范围(range)、字符串(str)、字节序列(bytes、bytearray) 元素按顺序排列,支持索引和切片操作
集合类型 集合(set)、冻结集合(frozenset) 元素无序且唯一,支持集合运算(交并差)
映射类型 字典(dict) 以键值对形式存储数据,通过键快速查找值

此外,还可以按"可变性"来区分:

  • 可变容器:列表(list)、集合(set)、字典(dict)、字节数组(bytearray)等,创建后可以增删改元素。
  • 不可变容器:元组(tuple)、冻结集合(frozenset)、字符串(str)、字节序列(bytes)等,一旦创建就不能修改内容。

Python 标准库中的 collections 模块还提供了许多高级容器,如 deque(双端队列)、namedtuple(命名元组)、Counter(计数器)、defaultdict(默认值字典)、OrderedDict(有序字典)等,它们在特定场景下比基础容器更加高效和便捷。

3. 使用容器的好处

在日常编程中,使用容器能带来以下显著优势:

  • 组织性强:将相关数据放在一个容器中,代码结构更清晰,逻辑更容易理解。比如用一个列表存放所有学生的成绩,而不是定义几十个零散变量。
  • 操作便捷:容器提供了丰富的内置方法(增删改查、排序、反转、过滤等),能大幅减少手写代码量,提升开发效率。
  • 内存高效:Python 容器在底层做了大量优化,相比手动管理分散的变量,容器对内存的利用率更高,访问速度也更快。
  • 可迭代性:所有容器都支持迭代,可以方便地用 for 循环遍历,结合推导式、map/filter 等高阶函数进行批量处理。
  • 类型丰富,按需选择:不同容器有各自的优势——需要去重用集合,需要快速查找用字典,需要保持顺序用列表。根据场景选择合适的容器,能极大优化程序性能。
  • 代码可维护性:统一的容器接口让代码更容易被他人理解和维护,也方便进行单元测试和调试。

4. 常用容器详解

4.1 列表(list)

列表是 Python 中最常用的可变序列容器,用方括号 [] 表示。它可以存放任意类型的元素,甚至是混合类型,并且支持动态扩容。

创建列表:

# 空列表
empty = []
包含元素的列表
fruits = ["apple", "banana", "cherry"]
使用 list() 构造函数
numbers = list(range(1, 6))  # [1, 2, 3, 4, 5]
列表推导式
squares = [x ** 2 for x in range(10)]  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

列表的特点:

  • 元素有序,按插入顺序排列。
  • 支持索引和切片:fruits[0]fruits[1:3]
  • 可变:可以随时添加、删除、修改元素。
  • 允许重复元素。
  • 时间复杂度:索引访问 O(1),末尾追加 O(1),插入/删除 O(n)。

适用场景:需要维护一组有序数据,且经常进行增删改操作的场景,如待办事项列表、用户记录列表、数据处理管道中的中间结果等。

4.2 元组(tuple)

元组是不可变的序列容器,用小括号 () 表示(也可省略括号)。一旦创建,元素就不能被修改、添加或删除。

# 创建元组
point = (3, 5)
colors = "red", "green", "blue"  # 括号可省略
单元素元组(注意逗号)
single = (42,)
嵌套元组
matrix = ((1, 2), (3, 4))

元组的特点:

  • 不可变:保证了数据的安全性,适合作为常量集合使用。
  • 有序,支持索引和切片。
  • 占用内存比列表小,创建速度更快。
  • 可以作为字典的键(列表不能)。
  • 支持"拆包"(unpacking):x, y = point

适用场景:表示固定不变的数据结构(如坐标、RGB 颜色值)、函数返回多个值、作为字典的键、保护不希望被意外修改的数据。

4.3 集合(set)

集合是无序且元素唯一的可变容器,用花括号 {}set() 创建。它基于哈希表实现,查找速度极快。

# 创建集合
empty_set = set()  # 注意:{} 创建的是空字典
numbers = {1, 2, 3, 4}
自动去重
unique = {1, 2, 2, 3, 3, 3}  # {1, 2, 3}
从列表去重
my_list = [1, 2, 2, 3, 3, 3]
unique_list = list(set(my_list))  # [1, 2, 3]

集合的特点:

  • 元素唯一:自动去重,这是集合最重要的特性。
  • 无序:不能通过索引访问元素。
  • 可变:可以添加和删除元素。
  • 元素必须是可哈希的(不可变类型),因此列表不能作为集合元素。
  • 支持数学集合运算:并集(|)、交集(&)、差集(-)、对称差集(^)。
  • 查找复杂度 O(1),非常高效。

适用场景:数据去重、成员资格快速检查(判断某元素是否存在)、集合运算(如求共同好友、差集筛选)、去除重复 URL 等。

4.4 字典(dict)

字典是 Python 中最核心的映射类型容器,以键值对(key-value)形式存储数据,用花括号 {} 表示。它是 Python 中查找效率最高的数据结构之一。

# 创建字典
person = {"name": "张三", "age": 28, "city": "北京"}
使用 dict() 构造函数
config = dict(host="localhost", port=8080)
字典推导式
squares = {x: x ** 2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

字典的特点:

  • 键值对存储:每个键(key)映射到一个值(value)。
  • 键必须唯一且可哈希(不可变类型),值可以是任意类型。
  • Python 3.7+ 字典保持插入顺序。
  • 可变:可以增删改键值对。
  • 查找、插入、删除复杂度均为 O(1)。

适用场景:需要快速根据键查找对应值的场景,如用户信息存储、配置管理、缓存系统、计数器、JSON 数据处理等。

4.5 其他高级容器(collections 模块)

Python 标准库中的 collections 模块提供了一些功能更强大的容器类型,是对基础容器的补充和扩展。

deque(双端队列)

deque(发音为 "deck")是双向队列,支持在两端高效地添加和删除元素,复杂度为 O(1),而列表在头部操作是 O(n)。

from collections import deque
dq = deque([1, 2, 3])
dq.append(4)       # 右端添加:[1, 2, 3, 4]
dq.appendleft(0)   # 左端添加:[0, 1, 2, 3, 4]
dq.pop()           # 右端删除:返回 4
dq.popleft()       # 左端删除:返回 0

适用场景:实现队列和栈、滑动窗口、最近使用记录(LRU 缓存)等。

namedtuple(命名元组)

namedtuple 是元组的子类,允许通过名称(而不仅是索引)访问字段,让代码更具可读性。

from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)
print(p.x)  # 10
print(p.y)  # 20
仍然是元组,支持索引和拆包
print(p[0])  # 10

适用场景:代替简单类、表示坐标/颜色/RGB 等轻量数据结构、从 CSV 或数据库读取记录。

Counter(计数器)

Counter 是字典的子类,专门用于统计元素出现的次数。

from collections import Counter
words = ["a", "b", "a", "c", "b", "a"]
count = Counter(words)
print(count)          # Counter({'a': 3, 'b': 2, 'c': 1})
print(count["a"])     # 3
print(count.most_common(2))  # [('a', 3), ('b', 2)]

适用场景:词频统计、字符频率分析、投票计数、数据分布统计。

defaultdict(默认值字典)

defaultdict 是字典的子类,当访问不存在的键时,会自动生成一个默认值,避免 KeyError 异常。

from collections import defaultdict
用 list 作为默认工厂
groups = defaultdict(list)
groups["语文"].append("张三")
groups["语文"].append("李四")
print(groups)  # defaultdict(<class 'list'>, {'语文': ['张三', '李四']})
没有 KeyError,自动创建空列表
print(groups["数学"])  # []

适用场景:分组操作、构建邻接表、统计多级数据等。

OrderedDict(有序字典)

在 Python 3.7 之前,普通字典不保证插入顺序。OrderedDict 提供了保证顺序的字典实现,并额外提供了 move_to_end() 等方法来重新排列元素。Python 3.7+ 中普通字典已有序,但 OrderedDict 仍保留了这些额外方法。

from collections import OrderedDict
od = OrderedDict()
od["first"] = 1
od["second"] = 2
od["third"] = 3
od.move_to_end("first")  # 将 "first" 移到最后
print(od)  # OrderedDict([('second', 2), ('third', 3), ('first', 1)])

适用场景:需要精确控制元素顺序的场景、实现 LRU 缓存、保持 JSON 键顺序。

5. 容器的常见操作

Python 容器提供了丰富的内置操作,以下按功能类别进行梳理。

5.1 增删改查(CRUD 操作)

# === 列表 ===
lst = [1, 2, 3]
lst.append(4)        # 末尾追加:[1, 2, 3, 4]
lst.insert(1, 99)    # 指定位置插入:[1, 99, 2, 3, 4]
lst.extend([5, 6])   # 扩展多个元素:[1, 99, 2, 3, 4, 5, 6]
lst.remove(99)       # 删除指定值:[1, 2, 3, 4, 5, 6]
popped = lst.pop(0)  # 按索引删除并返回:popped=1, lst=[2, 3, 4, 5, 6]
=== 字典 ===
d = {"a": 1}
d["b"] = 2           # 新增键值对
d["a"] = 10          # 修改值
value = d.get("c", 0) # 安全获取,不存在返回默认值 0
del d["b"]           # 删除键值对
d.pop("a")           # 删除并返回值
=== 集合 ===
s = {1, 2}
s.add(3)             # 添加元素
s.remove(2)          # 删除元素(不存在则报错)
s.discard(99)        # 安全删除(不存在不报错)

5.2 遍历与迭代

# 遍历列表
for item in [1, 2, 3]:
    print(item)
带索引遍历
for i, item in enumerate(["a", "b", "c"]):
print(i, item)
遍历字典
d = {"name": "张三", "age": 28}
for key in d:
print(key)
for key, value in d.items():
print(key, value)
同时遍历多个列表
for a, b in zip([1, 2], ["x", "y"]):
print(a, b)

5.3 切片操作(序列类型)

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[2:5])    # [2, 3, 4]  从索引 2 到 4
print(lst[:3])     # [0, 1, 2]  前三个
print(lst[-3:])    # [7, 8, 9]  后三个
print(lst[::2])    # [0, 2, 4, 6, 8]  步长为 2
print(lst[::-1])   # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]  反转

5.4 推导式(Comprehension)

# 列表推导式
squares = [x ** 2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
字典推导式
square_map = {x: x ** 2 for x in range(5)}
集合推导式
unique_lengths = {len(word) for word in ["apple", "banana", "cherry"]}

5.5 排序与反转

# 列表排序
lst = [3, 1, 4, 1, 5, 9]
lst.sort()                  # 原地排序:[1, 1, 3, 4, 5, 9]
lst.sort(reverse=True)      # 降序:[9, 5, 4, 3, 1, 1]
自定义排序
words = ["banana", "apple", "cherry"]
words.sort(key=len)         # 按长度排序:['apple', 'banana', 'cherry']
返回新列表
sorted_lst = sorted([3, 1, 2])  # [1, 2, 3]
反转
lst.reverse()               # 原地反转

5.6 成员检查

# 检查元素是否存在
fruits = ["apple", "banana", "cherry"]
print("apple" in fruits)     # True
print("grape" not in fruits) # True
字典中检查键
d = {"name": "张三"}
print("name" in d)           # True

5.7 内置函数

Python 提供了一系列与容器配套使用的内置函数:

  • len()返回容器中元素的个数。
  • max() / min()返回容器中的最大/最小元素。
  • sum()对数值容器求和。
  • any() / all()判断是否有/所有元素为真。
  • map() / filter()对容器元素进行映射和过滤。
  • zip()将多个容器按位置打包。
  • enumerate()为可迭代对象添加索引。
nums = [1, 2, 3, 4, 5]
print(len(nums))        # 5
print(max(nums))        # 5
print(sum(nums))        # 15
print(any([0, 0, 1]))   # True
print(all([1, 2, 3]))   # True
map 示例
doubled = list(map(lambda x: x * 2, nums))  # [2, 4, 6, 8, 10]
filter 示例
evens = list(filter(lambda x: x % 2 == 0, nums))  # [2, 4]

5.8 容器之间的转换

# 列表 ↔ 元组
tuple_from_list = tuple([1, 2, 3])   # (1, 2, 3)
list_from_tuple = list((1, 2, 3))    # [1, 2, 3]
列表 ↔ 集合(去重)
unique = list(set([1, 2, 2, 3]))     # [1, 2, 3]
列表 ↔ 字典
pairs = [("a", 1), ("b", 2)]
d = dict(pairs)                       # {'a': 1, 'b': 2}
items = list(d.items())               # [('a', 1), ('b', 2)]
字符串 ↔ 列表
chars = list("hello")                 # ['h', 'e', 'l', 'l', 'o']
joined = "".join(chars)               # "hello"

6. 总结

Python 容器是编程中最基础也最重要的工具之一。本文从是什么、为什么、有哪些、怎么用四个维度系统梳理了容器的核心知识:

  • 容器是什么:存放和管理多个元素的数据结构,是组织和操作数据的"容器"。
  • 容器的分类:主要分为序列类型(list、tuple)、集合类型(set、frozenset)和映射类型(dict),同时 collections 模块提供了 deque、namedtuple、Counter、defaultdict、OrderedDict 等高级容器。
  • 为什么用容器:提升代码组织性、操作便捷性、内存效率和可维护性,是编写高质量 Python 代码的基础。
  • 容器怎么用:掌握增删改查、遍历迭代、切片、推导式、排序、成员检查、内置函数和类型转换等核心操作,就能应对绝大多数开发场景。

在实际开发中,选择合适的容器至关重要:需要有序可变数据选列表,需要不可变安全数据选元组,需要去重和集合运算选集合,需要快速键值查找选字典。合理运用容器,能让代码更简洁、更高效、更 Pythonic。

建议读者在学习完本文后,动手实践每个容器类型的创建和常用操作,并结合 collections 模块尝试一些高级用法,这样能更快地将理论知识转化为实际编码能力。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐