全面解析Python内置数据结构及其使用示例
目录
1. 序列类型 (Sequence Types)
1.1 列表 (List)
特性: 有序、可变、允许重复元素
# 创建列表
fruits = ['apple', 'banana', 'cherry']
numbers = [1, 2, 3, 4, 5]
mixed = [1, 'hello', 3.14, True]
# 基本操作
fruits.append('orange') # 添加元素: ['apple', 'banana', 'cherry', 'orange']
fruits.insert(1, 'mango') # 插入元素: ['apple', 'mango', 'banana', ...]
fruits.remove('banana') # 删除指定值
last = fruits.pop() # 删除并返回最后一个元素
fruits.sort() # 原地排序
fruits.reverse() # 原地反转
# 切片操作
sublist = numbers[1:4] # [2, 3, 4]
reversed_list = numbers[::-1] # [5, 4, 3, 2, 1]
# 列表推导式
squares = [x**2 for x in range(10) if x % 2 == 0] # [0, 4, 16, 36, 64]
1.2 元组 (Tuple)
特性: 有序、不可变、允许重复元素
# 创建元组
coordinates = (10, 20)
single = (42,) # 单元素元组需要逗号
empty = ()
# 解包
x, y = coordinates
# 元组作为字典键(因为不可变)
locations = {
(0, 0): '原点',
(1, 0): '东',
(0, 1): '北'
}
# 具名元组 (Named Tuple)
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
print(p.x, p.y) # 11 22
print(p[0] + p[1]) # 33 (支持索引访问)
1.3 字符串 (String)
特性: 有序、不可变、Unicode字符序列
text = "Hello, Python!"
# 常用方法
text.upper() # "HELLO, PYTHON!"
text.lower() # "hello, python!"
text.startswith('Hello') # True
text.find('Python') # 7 (返回索引,找不到返回-1)
text.replace('Python', 'World') # "Hello, World!"
text.split(', ') # ['Hello', 'Python!']
'-'.join(['a', 'b', 'c']) # 'a-b-c'
# f-string 格式化
name = "Alice"
age = 25
info = f"{name} is {age} years old"
1.4 范围 (Range)
# range(start, stop, step)
range(5) # 0, 1, 2, 3, 4
range(1, 10) # 1到9
range(0, 10, 2) # 0, 2, 4, 6, 8
range(10, 0, -1) # 10到1的倒数
# 转换为列表
list(range(5)) # [0, 1, 2, 3, 4]
2. 集合类型 (Set Types)
2.1 集合 (Set)
特性: 无序、可变、元素唯一、不可哈希元素
# 创建集合
s1 = {1, 2, 3, 3, 3} # {1, 2, 3} (自动去重)
s2 = set([1, 2, 2, 3]) # {1, 2, 3}
s3 = set() # 空集合 (注意: {} 是空字典)
# 添加和删除
s1.add(4) # {1, 2, 3, 4}
s1.discard(5) # 删除元素,不存在不报错
s1.remove(3) # 删除元素,不存在报错 KeyError
# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a | b # 并集: {1, 2, 3, 4, 5, 6}
a & b # 交集: {3, 4}
a - b # 差集: {1, 2}
a ^ b # 对称差集: {1, 2, 5, 6}
# 集合推导式
s = {x for x in 'abracadabra' if x not in 'abc'} # {'r', 'd'}
2.2 冻结集合 (Frozenset)
特性: 不可变集合,可作为字典键或集合元素
fs = frozenset([1, 2, 3])
# fs.add(4) # 报错: AttributeError
# 可作为字典键
frozen_dict = {
frozenset([1, 2]): "一二",
frozenset([3, 4]): "三四"
}
3. 映射类型 (Mapping Types)
3.1 字典 (Dictionary)
特性: 键值对存储,键唯一且可哈希,Python 3.7+ 保持插入顺序
# 创建字典
person = {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
config = dict(host='localhost', port=8080)
empty = {}
# 访问和修改
person['name'] # 'Alice'
person.get('gender', 'unknown') # 'unknown' (安全获取)
person['age'] = 26 # 修改
person['gender'] = 'female' # 添加
# 删除
del person['city']
age = person.pop('age') # 删除并返回值
# 遍历
for key in person:
print(key, person[key])
for key, value in person.items():
print(f"{key}: {value}")
# 合并字典 (Python 3.9+)
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged = dict1 | dict2 # {'a': 1, 'b': 3, 'c': 4}
# 字典推导式
squares = {x: x**2 for x in range(6)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
3.2 默认字典 (defaultdict)
from collections import defaultdict
# 自动为不存在的键创建默认值
dd = defaultdict(list)
dd['fruits'].append('apple')
dd['fruits'].append('banana')
print(dd['fruits']) # ['apple', 'banana']
print(dd['vegetables']) # [] (自动创建空列表)
# 使用lambda设置默认值
counter = defaultdict(lambda: 0)
counter['a'] += 1 # 1
print(counter['b']) # 0
3.3 有序字典 (OrderedDict)
from collections import OrderedDict
# Python 3.7+ 普通字典已保持顺序,OrderedDict 提供额外功能
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# 移动到末尾
od.move_to_end('a') # 将'a'移到最后
od.move_to_end('b', last=False) # 将'b'移到开头
# 反转
reversed_od = OrderedDict(reversed(list(od.items())))
4. 高级数据结构
4.1 双端队列 (deque)
from collections import deque
# 创建双端队列
d = deque([1, 2, 3])
# 高效的两端操作
d.append(4) # 右侧添加: deque([1, 2, 3, 4])
d.appendleft(0) # 左侧添加: deque([0, 1, 2, 3, 4])
d.pop() # 右侧弹出: 4
d.popleft() # 左侧弹出: 0
# 旋转
d = deque([1, 2, 3, 4, 5])
d.rotate(2) # 向右旋转2位: deque([4, 5, 1, 2, 3])
d.rotate(-1) # 向左旋转1位: deque([5, 1, 2, 3, 4])
# 限制长度 (适合实现固定大小的缓存)
cache = deque(maxlen=3)
for i in range(10):
cache.append(i)
print(list(cache)) # [7, 8, 9] (只保留最后3个)
4.2 计数器 (Counter)
from collections import Counter
# 统计元素出现次数
text = "abracadabra"
count = Counter(text)
print(count) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# 获取最常见元素
print(count.most_common(2)) # [('a', 5), ('b', 2)]
# 集合运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
c1 + c2 # Counter({'a': 4, 'b': 3}) (相加)
c1 - c2 # Counter({'a': 2}) (相减,只保留正数)
c1 & c2 # Counter({'a': 1, 'b': 1}) (取最小)
c1 | c2 # Counter({'a': 3, 'b': 2}) (取最大)
4.3 堆队列 (heapq)
import heapq
# 堆(优先队列)- 最小堆
heap = [3, 1, 4, 1, 5, 9, 2, 6]
heapq.heapify(heap) # 转换为堆: [1, 1, 2, 3, 5, 9, 4, 6]
# 堆操作
heapq.heappush(heap, 0) # 添加元素
smallest = heapq.heappop(heap) # 弹出最小元素
# 获取n个最大/最小值
heapq.nsmallest(3, heap) # [1, 1, 2]
heapq.nlargest(3, heap) # [9, 6, 5]
# 合并多个有序列表
list1 = [1, 3, 5]
list2 = [2, 4, 6]
merged = list(heapq.merge(list1, list2)) # [1, 2, 3, 4, 5, 6]
4.4 数组 (array)
from array import array
# 类型码: 'i'有符号整数, 'f'浮点数, 'd'双精度浮点数等
arr = array('i', [1, 2, 3, 4, 5])
# 基本操作类似列表
arr.append(6)
arr.insert(0, 0)
arr.pop()
# 优势:比列表更节省内存(存储的是C类型数据)
# 适用于大量数值计算场景
5. 性能对比与选择建议
5.1 时间复杂度对比
| 操作 | 列表 | 集合 | 字典 | deque |
|---|---|---|---|---|
| 添加元素 | O(1) | O(1) | O(1) | O(1) |
| 删除元素 | O(n) | O(1) | O(1) | O(1) |
| 查找元素 | O(n) | O(1) | O(1) | O(n) |
| 索引访问 | O(1) | - | - | O(1) |
5.2 使用场景建议
| 场景 | 推荐数据结构 | 原因 |
|---|---|---|
| 需要有序序列 | list |
支持索引和切片 |
| 频繁两端操作 | deque |
O(1) 两端操作 |
| 去重和集合运算 | set |
自动去重,高效集合运算 |
| 键值对存储 | dict |
哈希表实现,O(1) 查找 |
| 需要默认值 | defaultdict |
自动处理缺失键 |
| 统计频率 | Counter |
内置计数功能 |
| 不可变序列 | tuple |
可作为字典键,线程安全 |
| 大量数值计算 | array |
内存效率高 |
5.3 性能测试示例
import time
# 列表 vs 集合查找性能对比
data_list = list(range(100000))
data_set = set(range(100000))
target = 99999
# 列表查找
start = time.time()
found = target in data_list
list_time = time.time() - start
# 集合查找
start = time.time()
found = target in data_set
set_time = time.time() - start
print(f"列表查找时间: {list_time:.6f}秒")
print(f"集合查找时间: {set_time:.6f}秒")
print(f"集合快 {list_time/set_time:.0f} 倍")
总结
Python 提供了丰富的内置数据结构,选择合适的数据结构可以显著提升代码的性能和可读性:
- 列表适合有序数据的存储和遍历
- 字典适合快速查找和键值映射
- 集合适合去重和集合运算
- 元组适合不可变数据和作为字典键
- deque适合队列和两端频繁操作的场景
- Counter适合频率统计
理解每种数据结构的特性和时间复杂度,是编写高效Python代码的关键。