在编程学习中,数据结构是构建高效程序的基石。Python 作为一门简洁而强大的语言,内置了多种实用的数据结构,帮助开发者轻松处理和组织数据。本文将带你全面了解 Python 的核心数据结构,并通过示例掌握它们的用法,为后续的算法和项目开发打下坚实基础。
一、为什么需要数据结构?
数据结构是计算机存储、组织数据的方式。选择合适的数据结构可以:
-
提高程序效率:例如,用字典查找元素比列表快得多。
-
简化代码逻辑:如集合自动去重,避免手动判断。
-
更贴合业务场景:比如用元组表示固定坐标,用列表存储动态数据。
Python 提供了丰富的内置数据结构,主要包括:列表(list) 、元组(tuple) 、字典(dict) 、集合(set) 。此外,还有 collections 模块中的高级结构(如 Counter、defaultdict 等),可根据需要选用。
二、列表(List):灵活的有序序列
列表是 Python 中最常用的数据结构,用方括号 [] 表示,可以存储任意类型的元素,并且有序、可变。
1. 基本操作
python
# 创建列表
fruits = ['apple', 'banana', 'cherry']
mixed = [1, 'hello', 3.14, True]
# 访问元素(索引从0开始)
print(fruits[0]) # apple
print(fruits[-1]) # cherry(负索引表示倒数)
# 修改元素
fruits[1] = 'blueberry'
print(fruits) # ['apple', 'blueberry', 'cherry']
# 添加元素
fruits.append('orange') # 末尾添加
fruits.insert(1, 'grape') # 指定位置插入
print(fruits) # ['apple', 'grape', 'blueberry', 'cherry', 'orange']
# 删除元素
fruits.remove('grape') # 删除第一个匹配项
popped = fruits.pop() # 弹出末尾元素(可指定索引)
del fruits[0] # 删除指定索引元素
print(fruits) # ['blueberry', 'cherry']
# 切片(获取子列表)
numbers = [0, 1, 2, 3, 4, 5]
print(numbers[1:4]) # [1, 2, 3](左闭右开)
print(numbers[:3]) # [0, 1, 2]
print(numbers[::2]) # [0, 2, 4](步长为2)
2. 常用方法与特性
-
len(list):获取长度 -
list.sort()/sorted(list):排序 -
list.reverse():反转 -
in运算符:检查元素是否存在 -
列表推导式:快速生成新列表
python
# 列表推导式示例:生成0~9的平方
squares = [x**2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 筛选偶数平方
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # [0, 4, 16, 36, 64]
适用场景:需要频繁增删改的有序集合,如待办事项列表、动态数据队列。
三、元组(Tuple):不可变的有序序列
元组用圆括号 () 表示,与列表类似,但一旦创建,元素不可修改。这种不可变性使元组更安全、更轻量,常用于表示固定数据。
1. 基本操作
python
# 创建元组
point = (10, 20)
colors = ('red', 'green', 'blue')
single = (42,) # 单元素元组必须加逗号,否则被当作括号运算符
# 访问元素(支持索引和切片)
print(point[0]) # 10
print(colors[1:3]) # ('green', 'blue')
# 尝试修改会报错
# point[0] = 5 # TypeError: 'tuple' object does not support item assignment
# 解包
x, y = point
print(f"x={x}, y={y}") # x=10, y=20
2. 元组与列表的选择
-
当数据不应被修改时(如坐标、配置项),优先用元组。
-
元组可作为字典的键(因为不可变),列表则不能。
-
元组占用内存更小,性能略高。
python
# 元组作为字典键
locations = {(35.68, 139.76): 'Tokyo', (40.71, -74.01): 'New York'}
适用场景:函数返回多个值、字典键、常量数据集合。
四、字典(Dictionary):键值对映射
字典用花括号 {} 表示,存储键-值对 ,键必须是不可变类型(如字符串、数字、元组),值可以是任意类型。字典是无序的(Python 3.7+ 保持插入顺序,但不应依赖顺序进行逻辑判断)。
1. 基本操作
python
# 创建字典
person = {
'name': 'Alice',
'age': 30,
'city': 'Beijing'
}
# 访问值
print(person['name']) # Alice
print(person.get('age')) # 30(推荐,键不存在返回None,不会报错)
print(person.get('salary', 0)) # 0(可指定默认值)
# 修改/添加键值对
person['age'] = 31
person['job'] = 'Engineer' # 键不存在则添加
print(person)
# 删除键值对
del person['city']
popped = person.pop('job') # 弹出指定键的值
# 遍历字典
for key, value in person.items():
print(f"{key}: {value}")
# 检查键是否存在
if 'name' in person:
print("Name exists")
2. 常用方法与技巧
-
keys()、values()、items():返回视图对象 -
字典推导式:快速生成字典
-
update():合并字典
python
# 字典推导式:交换键值
original = {'a': 1, 'b': 2, 'c': 3}
swapped = {v: k for k, v in original.items()}
print(swapped) # {1: 'a', 2: 'b', 3: 'c'}
# 合并字典
d1 = {'x': 1, 'y': 2}
d2 = {'y': 3, 'z': 4}
d1.update(d2) # 重复键会用d2的值覆盖
print(d1) # {'x': 1, 'y': 3, 'z': 4}
适用场景:需要通过唯一键快速查找数据的场景,如用户信息表、缓存、配置映射。
五、集合(Set):无序、不重复的元素集
集合用花括号 {} 或 set() 创建,与字典不同的是,集合只包含键,没有值。它的核心特性是元素唯一性 和集合运算(并集、交集等)。
1. 基本操作
python
# 创建集合
fruits = {'apple', 'banana', 'cherry'}
numbers = set([1, 2, 3, 2, 1]) # 从列表创建,自动去重
print(numbers) # {1, 2, 3}
# 添加元素
fruits.add('orange')
fruits.add('banana') # 已有元素不会重复添加
print(fruits) # {'apple', 'cherry', 'orange', 'banana'}
# 删除元素
fruits.remove('apple') # 不存在会报错
fruits.discard('grape') # 不存在不会报错(安全删除)
popped = fruits.pop() # 随机弹出一个元素
# 检查元素是否存在
if 'banana' in fruits:
print("Banana is in set")
2. 集合运算
python
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# 并集
print(a | b) # {1, 2, 3, 4, 5, 6}
print(a.union(b)) # 同上
# 交集
print(a & b) # {3, 4}
print(a.intersection(b))
# 差集(在a中但不在b中)
print(a - b) # {1, 2}
# 对称差集(并集减去交集)
print(a ^ b) # {1, 2, 5, 6}
# 子集判断
print({1, 2}.issubset(a)) # True
print(a.issuperset({1, 2})) # True
适用场景:去重、成员关系测试、数学集合运算(如共同好友、权限交集)。
六、其他实用数据结构
Python 的标准库 collections 提供了更高级的数据结构,满足特殊需求。
1. Counter:计数器
python
from collections import Counter
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
counter = Counter(words)
print(counter) # Counter({'apple': 3, 'banana': 2, 'orange': 1})
print(counter.most_common(2)) # [('apple', 3), ('banana', 2)]
2. defaultdict:带默认值的字典
python
from collections import defaultdict
# 当键不存在时,自动调用默认工厂函数创建值
dd = defaultdict(int) # 默认值为0
dd['a'] += 1
print(dd['a']) # 1
print(dd['b']) # 0(原本不存在,自动创建)
# 使用list作为默认值,方便分组
group = defaultdict(list)
group['fruits'].append('apple')
group['fruits'].append('banana')
print(group) # defaultdict(<class 'list'>, {'fruits': ['apple', 'banana']})
3. namedtuple:带字段名的元组
python
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p[0]) # 也支持索引访问
4. deque:双端队列
python
from collections import deque
dq = deque(['a', 'b', 'c'])
dq.append('d') # 右端添加
dq.appendleft('z') # 左端添加
print(dq) # deque(['z', 'a', 'b', 'c', 'd'])
dq.pop() # 右端弹出
dq.popleft() # 左端弹出
七、如何选择合适的数据结构?
| 数据结构 | 特性 | 常用操作复杂度 | 适用场景 |
|---|---|---|---|
| 列表 | 有序、可变 | 索引 O(1),追加 O(1),插入/删除 O(n) | 动态数组,按顺序存储 |
| 元组 | 有序、不可变 | 索引 O(1) | 固定数据,作为字典键 |
| 字典 | 键值映射 | 查找/插入/删除 平均 O(1) | 通过键快速查找,关联数据 |
| 集合 | 无序、不重复 | 查找/插入/删除 平均 O(1) | 去重,集合运算 |
| deque | 双端队列 | 两端操作 O(1) | 队列、栈 |
选择建议:
-
如果只需要存储一系列元素,且可能修改 → 列表。
-
如果需要存储固定数据,确保不被意外修改 → 元组。
-
如果需要通过唯一标识快速查找值 → 字典。
-
如果需要去重或数学集合运算 → 集合。
-
如果需要频繁在两端插入删除 → deque。
-
如果需要计数或分组 → Counter / defaultdict。
八、总结
Python 的数据结构设计简洁而强大,掌握它们不仅能让代码更优雅,还能显著提升程序性能。从基础的列表、元组、字典、集合,到 collections 模块中的高级工具,每种结构都有其独特的定位。学习时多动手写示例,理解其背后的原理和适用场景,你会发现数据处理变得得心应手。
希望这篇文章能帮助你打下扎实的基础,在编程之路上更进一步!如果你有任何疑问或想深入探讨某个结构,欢迎留言交流。
练习题:
-
使用列表推导式生成 1 到 50 中所有能被 3 整除的数的平方。
-
创建一个字典,存储你最喜欢的几本书(书名: 作者),然后遍历打印。
-
有两个列表
list1 = [1, 2, 3, 4, 5]和list2 = [4, 5, 6, 7, 8],找出它们的交集和并集(使用集合)。 -
使用
Counter统计一段文本中每个单词出现的次数。
扩展阅读 :Python 官方文档 Data Structures 和 collections 模块。