【Python】迭代器(Iterator)vs 生成器(Generator)

迭代器(Iterator) vs 生成器(Generator)

  • 1.迭代器(Iterator)
    • 1.1 是什么?
    • 1.2 示例
    • 1.3 适用场景
  • 2.生成器(Generator)
    • 2.1 是什么?
    • 2.2 示例
    • 2.3 适用场景
  • 3.迭代器 vs 生成器
  • 4.如何选择?
  • 5.经典例子
    • 5.1 读取大文件(生成器更优)
    • 5.2 自定义树遍历(迭代器更优)
  • 6.总结

1.迭代器(Iterator)

1.1 是什么?

  • 迭代器是一个 可以逐个访问元素的对象,比如 listdictset 都可以通过 iter() 转换成迭代器。
  • 它必须实现 __iter__()__next__() 方法。
  • 特点
    • 只能前进,不能后退。
    • 遍历结束后,再调用 next() 会抛出 StopIteration 错误。

1.2 示例

my_list = [1, 2, 3]
it = iter(my_list)  # 转换成迭代器

print(next(it))  # 输出 1
print(next(it))  # 输出 2
print(next(it))  # 输出 3
print(next(it))  # 抛出 StopIteration

1.3 适用场景

  • 大数据遍历(如逐行读取大文件,避免内存爆炸)。
  • 自定义遍历逻辑(如树的深度优先遍历,就像《迭代器与生成器(一)》中的 DepthFirstIterator)。

2.生成器(Generator)

2.1 是什么?

  • 生成器是一种 特殊的迭代器,用 yield 关键字定义。
  • 特点
    • 惰性计算(需要时才计算,节省内存)。
    • 代码更简洁,不用手动实现 __iter____next__
    • 可以用 for 循环直接遍历。

2.2 示例

def count_up_to(n):
    i = 1
    while i <= n:
        yield i  # 每次 next() 调用时返回 i,并暂停在这里
        i += 1

gen = count_up_to(3)  # 返回生成器对象

print(next(gen))  # 输出 1
print(next(gen))  # 输出 2
print(next(gen))  # 输出 3
print(next(gen))  # 抛出 StopIteration

# 也可以用 for 循环
for num in count_up_to(3):
    print(num)  # 输出 1, 2, 3

2.3 适用场景

  • 处理大数据流(如逐行读取日志文件)。
  • 无限序列(如斐波那契数列)。
  • 协程(Coroutine)(结合 yield 实现异步编程)。

3.迭代器 vs 生成器

特性 迭代器(Iterator) 生成器(Generator)
定义方式 需要实现 __iter____next__ yield 定义函数
内存占用 可能占用较大内存(如 list 惰性计算,省内存
代码简洁度 较复杂(需手动实现) 更简洁
适用场景 自定义遍历逻辑 惰性计算、无限序列、协程

4.如何选择?

  • 用迭代器
    • 需要自定义遍历逻辑(如树、图的遍历)。
    • 需要更底层的控制(如手动调用 next())。
  • 用生成器
    • 需要 惰性计算(如处理大文件、无限序列)。
    • 代码要更简洁(避免手动实现 __next__)。

5.经典例子

5.1 读取大文件(生成器更优)

def read_large_file(file_path):
    with open(file_path, "r") as f:
        for line in f:
            yield line  # 逐行读取,不占内存

for line in read_large_file("huge_log.txt"):
    print(line)

生成器更合适,因为文件可能很大,直接 read() 会爆内存。

5.2 自定义树遍历(迭代器更优)

class Tree:
    def __init__(self, value):
        self.value = value
        self.children = []

    def __iter__(self):
        return DepthFirstIterator(self)  # 自定义迭代器

迭代器更合适,因为需要控制遍历顺序(如深度优先、广度优先)。

6.总结

  • 迭代器:适合 自定义遍历逻辑(如树、图)。
  • 生成器:适合 惰性计算(如大文件、无限序列)。
  • 生成器是迭代器的“语法糖”,能用生成器的地方尽量用生成器,代码更简洁!

希望本文能让你搞懂迭代器和生成器!

你可能感兴趣的:(#,Python,基础,python,迭代器,生成器,iterator,generator,yield)