第九章:迭代器、生成器与推导式
9.1 迭代器
迭代器是一种可以被遍历的对象,它实现了 __iter__()
和 __next__()
方法。
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 28
|
iter_str = iter("Python")
print(next(iter_str)) print(next(iter_str)) print(next(iter_str)) print(next(iter_str)) print(next(iter_str)) print(next(iter_str))
for char in iter_str: print(char)
iter_str2 = "Python".__iter__() print(iter_str2.__next__())
try: while True: print(next(iter_str2)) except StopIteration: print("迭代完成")
|
自定义迭代器
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
counter = CountDown(5) for num in counter: print(num)
|
for 循环的工作原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| def my_for(iterable, callback): iterator = iter(iterable) while True: try: item = next(iterator) callback(item) except StopIteration: break
my_for("abc", lambda x: print(x))
for x in "abc": print(x)
|
9.2 生成器
生成器是一种特殊的迭代器,使用 yield
语句而不是 return
语句返回值。每次调用 next()
时,生成器函数从上次离开的地方继续执行
yield
相比较 return
关键字在于 yield 属于“等一下再离开”,每次调用 yield 都会返回不同的值,也就是每一次循环便利都会返回下一个 yield,直到没有
在这里我们简单的了解一下 yield 关键字,到了并发编程中,yiled 还会有一些常见的用途,如:
1、形成生成器
2、协程
3.上下文管理器
4、yield from
1 2 3 4 5 6 7 8 9 10 11
| def simple_generator(): yield 1 yield 2 yield 3 gen = simple_generator() print(next(gen)) print(next(gen)) print(next(gen))
|
生成器表达式(推导式)
1 2 3 4 5 6
| even_numbers = (x for x in range(10) if x % 2 == 0)
for num in even_numbers: print(num)
|
生成器的优势
- 内存效率:生成器不会一次性生成所有值,而是按需生成,降低内存使用
- 延迟计算:只有在请求下一个值时才执行计算
- 无限序列:可以表示理论上无限的数据流
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
def get_lines_list(file_path): result = [] with open(file_path, 'r') as f: for line in f: result.append(line.strip()) return result
def get_lines_generator(file_path): with open(file_path, 'r') as f: for line in f: yield line.strip()
|
生成器应用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def batch_processor(items, batch_size=100): """将大列表分成小批次处理""" batch = [] for item in items: batch.append(item) if len(batch) == batch_size: yield batch batch = [] if batch: yield batch
items = list(range(1050)) for batch in batch_processor(items, 300): print(f"处理批次,大小: {len(batch)}")
|
9.3 推导式
推导式是创建数据集合的简洁方法。
列表推导式
1 2 3 4 5 6 7 8 9 10 11 12
| [表达式 for 变量 in 可迭代对象 if 条件]
squares = [x**2 for x in range(1, 11)]
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] flattened = [x for row in matrix for x in row]
|
字典推导式
1 2 3 4 5 6 7 8 9
| {键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}
squares_dict = {x: x**2 for x in range(1, 6)}
original = {'a': 1, 'b': 2, 'c': 3} inverted = {v: k for k, v in original.items()}
|
集合推导式
1 2 3 4 5 6 7 8 9
| {表达式 for 变量 in 可迭代对象 if 条件}
squares_set = {x**2 for x in range(1, 11)}
words = ['hello', 'world', 'hello', 'python'] unique_lengths = {len(word) for word in words}
|
生成器表达式
1 2 3 4 5 6 7 8
| (表达式 for 变量 in 可迭代对象 if 条件)
squares_gen = (x**2 for x in range(1, 11))
sum_of_squares = sum(x**2 for x in range(1, 11))
|
三元表达式
1 2 3 4 5 6 7 8 9 10
| 值1 if 条件 else 值2
x, y = 10, 20 larger = x if x > y else y
values = [1, 2, 3, 4, 5] result = [x*2 if x % 2 == 0 else x*3 for x in values]
|