1. 什么是迭代器?
迭代器(Iterator)是 Python 中一种实现了迭代协议的对象,它允许我们逐个访问集合中的元素,而不需要知道集合的内部结构。迭代器必须实现两个方法:
__iter__():返回迭代器对象本身
__next__():返回下一个元素,如果没有更多元素则抛出 StopIteration 异常
1.1 迭代器的基本使用
1 2 3 4 5 6 7 8 9 10 11 12
| numbers = [1, 2, 3, 4, 5] iterator = iter(numbers)
print(next(iterator)) print(next(iterator)) print(next(iterator))
for num in iterator: print(num)
|
1.2 自定义迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Countdown: def __init__(self, start): self.start = start def __iter__(self): return self def __next__(self): if self.start <= 0: raise StopIteration self.start -= 1 return self.start + 1
countdown = Countdown(5) for num in countdown: print(num)
|
2. 什么是可迭代对象?
可迭代对象(Iterable)是指实现了 __iter__() 方法的对象,它可以生成一个迭代器。常见的可迭代对象包括:
- 序列类型:列表、元组、字符串
- 集合类型:集合、字典
- 文件对象
- 生成器
2.1 检查可迭代对象
1 2 3 4 5 6
| from collections.abc import Iterable
print(isinstance([], Iterable)) print(isinstance({}, Iterable)) print(isinstance("hello", Iterable)) print(isinstance(123, Iterable))
|
2.2 可迭代对象与迭代器的区别
- 可迭代对象:实现了
__iter__() 方法,返回一个迭代器
- 迭代器:实现了
__iter__() 和 __next__() 方法,用于逐个访问元素
3. 什么是生成器?
生成器(Generator)是一种特殊的迭代器,它使用 yield 语句来产生值,而不是一次性计算所有值。生成器具有惰性计算的特性,只在需要时才生成值,从而节省内存。
3.1 生成器表达式
1 2 3 4 5 6 7
| squares = (x ** 2 for x in range(10)) print(type(squares))
for square in squares: print(square)
|
3.2 生成器函数
1 2 3 4 5 6 7 8
| def countdown(n): while n > 0: yield n n -= 1
for num in countdown(5): print(num)
|
4. 生成器的工作原理
生成器函数在执行时,会在遇到 yield 语句时暂停执行,保存当前的状态(包括局部变量和执行位置),并返回 yield 后面的值。当再次调用 next() 函数时,生成器会从暂停的位置继续执行,直到遇到下一个 yield 语句或函数结束。
4.1 生成器的状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| def simple_generator(): print("开始执行") yield 1 print("继续执行") yield 2 print("执行结束")
gen = simple_generator()
print(next(gen))
print(next(gen))
print(next(gen))
|
5. 生成器的高级特性
5.1 生成器的 send() 方法
生成器的 send() 方法可以向生成器发送值,并恢复执行。
1 2 3 4 5 6 7 8 9 10 11
| def echo_generator(): response = yield "请输入一个值:" while response != "exit": response = yield f"你输入的是:{response}"
gen = echo_generator() print(next(gen)) print(gen.send("Hello")) print(gen.send("World")) print(gen.send("exit"))
|
5.2 生成器的 throw() 方法
生成器的 throw() 方法可以向生成器抛出异常。
1 2 3 4 5 6 7 8 9 10 11 12
| def error_generator(): try: yield 1 yield 2 yield 3 except ValueError as e: yield f"捕获到异常:{e}"
gen = error_generator() print(next(gen)) print(gen.throw(ValueError, "自定义错误"))
|
5.3 生成器的 close() 方法
生成器的 close() 方法可以关闭生成器,释放资源。
1 2 3 4 5 6 7 8 9 10 11 12
| def infinite_generator(): i = 0 while True: yield i i += 1
gen = infinite_generator() print(next(gen)) print(next(gen)) gen.close() print(next(gen))
|
6. 迭代器和生成器的应用场景
6.1 处理大型数据集
1 2 3 4 5 6 7 8 9
| def read_large_file(filename): with open(filename, 'r') as f: for line in f: yield line.strip()
for line in read_large_file('large_file.txt'): process_line(line)
|
6.2 实现无限序列
1 2 3 4 5 6 7 8 9 10
| def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
fib = fibonacci() for _ in range(10): print(next(fib))
|
6.3 管道处理数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| def filter_even(numbers): for num in numbers: if num % 2 == 0: yield num
def square(numbers): for num in numbers: yield num ** 2
def sum_numbers(numbers): total = 0 for num in numbers: total += num return total
numbers = range(10) even_numbers = filter_even(numbers) squared_numbers = square(even_numbers) total = sum_numbers(squared_numbers) print(total)
|
7. 迭代工具
Python 提供了一些内置的迭代工具,用于处理可迭代对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import itertools
counter = itertools.count(1) print(next(counter)) print(next(counter))
cycler = itertools.cycle(['A', 'B', 'C']) print(next(cycler)) print(next(cycler)) print(next(cycler)) print(next(cycler))
repeater = itertools.repeat('Hello', 3) for item in repeater: print(item)
|
7.2 内置函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| numbers = [1, 2, 3, 4, 5] squared = map(lambda x: x ** 2, numbers) print(list(squared))
evens = filter(lambda x: x % 2 == 0, numbers) print(list(evens))
names = ['Alice', 'Bob', 'Charlie'] ages = [25, 30, 35] for name, age in zip(names, ages): print(f"{name}: {age}")
|
8. 生成器表达式与列表推导式的对比
8.1 内存使用
1 2 3 4 5 6 7 8 9
| import sys
list_comp = [x ** 2 for x in range(1000000)] print(f"列表推导式内存使用: {sys.getsizeof(list_comp)} 字节")
gen_expr = (x ** 2 for x in range(1000000)) print(f"生成器表达式内存使用: {sys.getsizeof(gen_expr)} 字节")
|
8.2 执行速度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import time
tart = time.time() list_comp = [x ** 2 for x in range(1000000)] sum(list_comp) end = time.time() print(f"列表推导式耗时: {end - start:.6f} 秒")
start = time.time() gen_expr = (x ** 2 for x in range(1000000)) sum(gen_expr) end = time.time() print(f"生成器表达式耗时: {end - start:.6f} 秒")
|
9. 自定义可迭代对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class MyRange: def __init__(self, start, end, step=1): self.start = start self.end = end self.step = step def __iter__(self): return self.MyRangeIterator(self) class MyRangeIterator: def __init__(self, my_range): self.my_range = my_range self.current = my_range.start def __iter__(self): return self def __next__(self): if self.current >= self.my_range.end: raise StopIteration value = self.current self.current += self.my_range.step return value
for i in MyRange(0, 10, 2): print(i)
|