一、 迭代器 (Iterator)

基本概念

迭代器是一个可以记住遍历位置的对象,实现了迭代器协议(__iter__() 和 __next__() 方法)

创建自定义迭代器

class MyIterator:
    def __init__(self, max_value):
        self.max_value = max_value
        self.current = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current < self.max_value:
            self.current += 1
            return self.current - 1
        else:
            raise StopIteration

# 使用自定义迭代器
my_iter = MyIterator(5)
for num in my_iter:
    print(num)  # 输出: 0, 1, 2, 3, 4

内置迭代器使用 iter()

# 列表迭代器
my_list = [1, 2, 3]
list_iter = iter(my_list)

print(next(list_iter))  # 1
print(next(list_iter))  # 2
print(next(list_iter))  # 3

# 字典迭代器
my_dict = {'a': 1, 'b': 2}
dict_iter = iter(my_dict.items())

for key, value in dict_iter:
    print(f"{key}: {value}")

二、 生成器 (Generator)

生成器函数

使用 yield 关键字创建生成器函数。

def my_generator(max_value):
    current = 0
    while current < max_value:
        yield current
        current += 1

# 使用生成器
gen = my_generator(5)
for num in gen:
    print(num)  # 输出: 0, 1, 2, 3, 4

生成器表达式

类似列表推导式,但使用圆括号。

# 生成器表达式
squares_gen = (x**2 for x in range(5))

for square in squares_gen:
    print(square)  # 输出: 0, 1, 4, 9, 16

# 与列表推导式的区别
squares_list = [x**2 for x in range(5)]  # 立即计算所有值

高级生成器用法

def fibonacci_generator(limit):
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

# 生成斐波那契数列
fib_gen = fibonacci_generator(10)
for num in fib_gen:
    print(num)

三、 主要区别

在这里插入图片描述

四、 注意事项

迭代器注意事项

# 1. 迭代器只能遍历一次
my_list = [1, 2, 3]
my_iter = iter(my_list)

print(list(my_iter))  # [1, 2, 3]
print(list(my_iter))  # [] - 空列表,因为迭代器已耗尽

# 2. 手动处理 StopIteration
my_iter = iter([1, 2, 3])
try:
    while True:
        item = next(my_iter)
        print(item)
except StopIteration:
    print("迭代结束")

生成器注意事项

# 1. 生成器表达式只能使用一次
squares = (x**2 for x in range(3))
print(sum(squares))  # 5 (0+1+4)
print(sum(squares))  # 0 - 生成器已耗尽

# 2. yield 的返回值
def generator_with_send():
    received = yield "开始"
    yield f"收到: {received}"

gen = generator_with_send()
print(next(gen))      # "开始"
print(gen.send("Hello"))  # "收到: Hello"

# 3. 生成器关闭
def infinite_generator():
    i = 0
    try:
        while True:
            yield i
            i += 1
    except GeneratorExit:
        print("生成器被关闭")

gen = infinite_generator()
print(next(gen))  # 0
gen.close()       # 输出: "生成器被关闭"

五、 实用技巧

管道式处理

def read_lines(filename):
    with open(filename, 'r') as file:
        for line in file:
            yield line.strip()

def filter_comments(lines):
    for line in lines:
        if not line.startswith('#'):
            yield line

def make_uppercase(lines):
    for line in lines:
        yield line.upper()

# 组合生成器管道
lines = read_lines('example.txt')
filtered = filter_comments(lines)
uppercased = make_uppercase(filtered)

for line in uppercased:
    print(line)

惰性求值

def process_data(data):
    # 模拟耗时操作
    print("处理数据...")
    return data * 2

def lazy_processor(data_list):
    for data in data_list:
        yield process_data(data)

# 只有在需要时才处理数据
data = [1, 2, 3, 4, 5]
lazy_gen = lazy_processor(data)

# 只处理前3个元素
for i, result in enumerate(lazy_gen):
    if i >= 3:
        break
    print(result)

六、 性能比较

import time
import sys

# 内存使用比较
def memory_usage():
    list_comp = [x**2 for x in range(1000000)]
    gen_expr = (x**2 for x in range(1000000))
    
    print(f"列表推导式内存: {sys.getsizeof(list_comp)} 字节")
    print(f"生成器表达式内存: {sys.getsizeof(gen_expr)} 字节")

# 执行时间比较
def timing_comparison():
    # 列表推导式(立即执行)
    start = time.time()
    result1 = sum([x**2 for x in range(1000000)])
    time1 = time.time() - start
    
    # 生成器表达式(惰性执行)
    start = time.time()
    result2 = sum((x**2 for x in range(1000000)))
    time2 = time.time() - start
    
    print(f"列表推导式时间: {time1:.4f}秒")
    print(f"生成器表达式时间: {time2:.4f}秒")

memory_usage()
timing_comparison()

总结

  1. 迭代器适用于需要复杂状态管理的场景
  2. 生成器更适用于简单的序列生成,代码更简洁
  3. 两者都支持惰性求值,节省内存
  4. 生成器只能遍历一次,迭代器根据实现可能支持多次遍历
  5. 在处理大数据集时,生成器通常更高效

根据具体需求选择合适的工具,在大多数序列处理场景中,生成器是更优的选择。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐