Python 数据结构与迭代器
Python 数据结构与迭代器详解:从列表到生成器
Python 提供了丰富且高效的数据结构(如 list、tuple、dict、set),以及强大的序列操作和惰性计算机制(如 generator 和 iterator)。掌握这些核心概念,是写出简洁、高效、Pythonic 代码的关键。
本文将系统梳理你日常开发中最常用的数据结构操作,并深入讲解迭代器与生成器的原理与应用。
一、列表(List):最灵活的序列
1. 基础特性
- 可变、有序、允许重复、支持混合类型。
list1 = [1, 2, 3]
list2 = ['a', 'b', 'v']
list3 = [1, 2, [1, 2, 3]] # 嵌套
2. 索引与切片
# 正向索引(0 起始)
print(list1[0]) # 1
# 负向索引(-1 为末尾)
print(list2[-1]) # 'v'
# 切片:左闭右开,[start:stop:step]
res = list1[:] # 全拷贝
res2 = list1[1:3] # [2, 3]
res3 = list1[1:3:2] # [2]
print(list1[-1:-3:-1]) # [5, 4](倒序取)
✅ 切片不会修改原列表,而是返回新列表。
3. 增删改查
list1 = [1, 2, 3]
# 增
list1.append(1) # 末尾添加 → [1,2,3,1]
list1.insert(2, 4) # 指定位置插入 → [1,2,4,3,1]
list1.extend([2, 3, 4]) # 批量追加元素 → [1,2,4,3,1,2,3,4]
# 删
res = list1.pop(1) # 删除索引 1 并返回值
list1.remove(3) # 删除第一个值为 3 的元素
del list1[2] # 删除索引 2
list1.clear() # 清空列表
# 改
list1[2] = 10 # 直接赋值更新
4. 常用方法
list1 = [1, 3, 2, 3, 4]
print(list1.index(2)) # 2(首次出现的索引)
print(list1.count(3)) # 2(出现次数)
list1.reverse() # 原地反转 → [4,3,2,3,1]
list1.sort() # 原地升序排序
list1.sort(reverse=True) # 倒序
list1.sort(key=lambda x: -x) # 自定义排序逻辑
⚠️ 注意:
sort()是原地操作,不返回新列表;若需新列表,请用sorted(list1)。
5. 遍历方式
num = [1, 2, 3]
# 方式1:直接遍历元素
for i in num:
print(i)
# 方式2:通过索引
for index in range(len(num)):
print(num[index])
# 方式3:同时获取索引和值(推荐!)
for index, item in enumerate(num):
print(index, item)
二、元组(Tuple):不可变的序列
- 不可变、有序、支持索引和切片。
- 常用于函数返回多个值、作为字典键(因 hashable)。
tp = (1, 2, 3, 4, 5, 6, 7, 8, 9)
tp2 = tuple([1]) # 单元素元组必须加逗号:(1,)
print(tp[1]) # 2
print(tp.index(9)) # 8
print(tp.count(9)) # 1
✅ 优势:比列表更节省内存,线程安全。
三、字典(Dict):键值对映射
scores = {}
scores['A'] = {2, 3, 4} # 值可以是集合
scores['A'].add(5)
print('A' in scores) # True
print(scores.get('B')) # None(安全访问)
# 遍历
for k, v in scores.items():
print(k, v)
# 或仅遍历键
for score in scores:
print(score, scores[score])
💡 字典在 Python 3.7+ 保持插入顺序。
四、集合(Set):无序唯一元素容器
1. 基本特性
- 无序、元素唯一、可变(
set)或不可变(frozenset)。 - 元素必须是可哈希的(不能是
list、dict等可变对象)。
s1 = {1, 2, 3, 4, 4, 3} # 自动去重 → {1,2,3,4}
s2 = {'a', 'b', 'b', 'c'} # → {'a','b','c'}
# 不可变集合
s4 = frozenset({1, 2, 3})
# s4.add(10) # ❌ 报错!
2. 增删改查
s1 = {1, 2, 3}
s1.add(4) # 添加
s1.update([2, 3, 4]) # 批量添加(自动去重)
s1.remove(4) # 删除(不存在则报错)
s1.discard(4) # 删除(不存在不报错)
s1.pop() # 随机弹出一个元素
s1.clear() # 清空
print(4 in s1) # 成员检查
3. 集合运算(数学操作)
s1 = {1, 2, 3}
s2 = {3, 5, 6}
# 并集
print(s1 | s2) # {1,2,3,5,6}
# 交集
print(s1 & s2) # {3}
# 差集(s1 - s2)
print(s1 - s2) # {1,2}
# 对称差集(无交集部分的并集)
print(s1 ^ s2) # {1,2,5,6}
✅ 运算符 vs 方法:
s1.difference(s2)等价于s1 - s2s1.difference_update(s2)会原地修改s1
4. 实用场景:去重
l1 = ['b','c','d','c','a','a']
# 方法1:利用 set(但会丢失顺序)
print(list(set(l1))) # 顺序不确定
# 方法2:手动去重(保持顺序)
l2 = []
for i in l1:
if i not in l2:
l2.append(i)
print(l2) # ['b','c','d','a']
🔜 Python 3.7+ 可用
dict.fromkeys(l1)保持顺序去重。
五、序列通用操作
1. 拼接与重复
list1 = [1, 2]
list2 = [3, 4]
print(list1 + list2) # [1,2,3,4]
print(list1 * 3) # [1,2,1,2,1,2]
tp1 = (1, 2)
print(tp1 * 2) # (1,2,1,2)
print('*****' * 6) # **************************
2. 解包(Unpacking)
def unpack(*args):
print(f'类型: {type(args)}, 参数: {args}')
a1 = (1, 2, 3, 4)
a2 = [1, 2, 3, 4, 5]
unpack(*a1) # (1,2,3,4)
unpack(*a2) # (1,2,3,4,5)
unpack(a1) # ((1,2,3,4),) ← 整个元组作为单个参数
✅
*用于“展开”可迭代对象,常用于函数调用、列表合并等。
六、字符串:也是序列!
字符串支持所有序列操作:
s = 'pumas are large,@cat like animals'
print(s[0]) # 'p'
print(s[-1]) # 's'
print(s[0:3]) # 'pum'
print(s[-3:-1]) # 'al'
# 分割
arr = s.split('@') # ['pumas are large,', 'cat like animals']
print(type(arr)) # <class 'list'>
# 统计与替换
print(s.count('a')) # 出现次数
print(s.replace('a', 'c'))
# 去除首尾字符
print(s.strip('123')) # 若首尾是 '1','2','3' 则去除
# 遍历
for c in s:
print(c)
七、迭代器(Iterator)与生成器(Generator)
📚 本节内容基于你提供的详细笔记,已做精炼整合。
核心概念关系链:
可迭代对象(Iterable)
→ iter() →
迭代器(Iterator)
→ next() →
逐个取值
而 生成器(Generator) 是一种特殊的迭代器。
| 概念 | 特点 |
|---|---|
| 可迭代对象 | 实现 __iter__(),如 list, str, dict |
| 迭代器 | 实现 __iter__() 和 __next__(),只能向前遍历一次 |
| 生成器 | 用 yield 或 (表达式) 创建,自动实现迭代器协议 |
1. 生成器函数(使用 yield)
def fibonacci(n):
a, b = 0, 1
while n > 0:
yield a
a, b = b, a + b
n -= 1
# 使用
for num in fibonacci(5):
print(num) # 0, 1, 1, 2, 3
✅ 优势:惰性求值,内存友好,适合大数据流。
2. 生成器表达式
# 列表推导式(立即计算,占内存)
list1 = [n * n for n in fibonacci(10)]
# 生成器表达式(惰性,不占内存)
list2 = (n * n for n in fibonacci(10))
print(list1) # [0, 1, 1, 4, 9, ...]
for n in list2:
print(n, end=", ") # 0, 1, 1, 4, 9, ...
⚠️ 注意:生成器只能遍历一次,用完即废。
3. 实际应用场景
-
处理大文件:
def read_large_file(path): with open(path) as f: for line in f: yield line.strip() -
无限序列:
def natural_numbers(): n = 1 while True: yield n n += 1 -
管道式数据处理:
def square(nums): for n in nums: yield n * n def even_filter(nums): for n in nums: if n % 2 == 0: yield n data = range(1, 6) result = even_filter(square(data)) print(list(result)) # [4, 16]
八、快速排序(Quick Sort)示例
def quick_sort(list1):
if len(list1) <= 1:
return list1
pivot = list1[0]
left = [x for x in list1[1:] if x < pivot]
right = [x for x in list1[1:] if x >= pivot]
return quick_sort(left) + [pivot] + quick_sort(right)
print(quick_sort([1, 2, 3, 9, 8, 4, 5, 6, 7]))
# 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
💡 虽然 Python 内置
sorted()更高效,但手写快排有助于理解分治思想。
总结:数据结构选择指南
| 需求 | 推荐类型 |
|---|---|
| 有序、可变、允许重复 | list |
| 有序、不可变 | tuple |
| 键值映射 | dict |
| 唯一元素、集合运算 | set |
| 大数据流、惰性计算 | generator |
| 高性能数值计算 | 考虑 array 或 numpy |
🐍 Python 之禅:
“There should be one — and preferably only one — obvious way to do it.”
但 Python 也提供了多种工具,让你在不同场景下选择最合适的方式。
希望这篇系统总结能帮助你巩固 Python 数据结构与迭代器的核心知识!动手运行每个示例,尝试修改参数,是掌握它们的最佳途径。欢迎分享你的实践心得!
本文由mdnice多平台发布
欢迎转载,不必注明出处

浙公网安备 33010602011771号