68人参与 • 2026-10-11 • Python
结论先行:迭代器(iterator)和生成器(generator)不是并列关系——生成器是迭代器的一种"偷懒写法"。所有生成器都是迭代器,但迭代器不一定是生成器。一句话区分:迭代器是"会挨个吐值的对象"(实现 __iter__ + __next__),生成器是用 yield 或生成器表达式"现写现用"造出的那种迭代器,最大的不同是它懒**,要一个才生一个,不占内存。**
能 for x in obj 挨个取值的对象,都叫"可迭代对象"(iterable,有 __iter__)。而迭代器是"被迭代时记住自己走到哪"的那个东西——它多了个 __next__,每次调用吐下一个,吐完抛 stopiteration。
lst = [1, 2, 3] it = iter(lst) # list 是可迭代对象,iter() 造出它的迭代器 print(next(it)) # 1 print(next(it)) # 2
关键点:list 本身不是迭代器(它可被多次 iter()),但 it 是。for 循环干的事,本质就是反复 next() 直到 stopiteration。
手写一个完整的迭代器类,要实现 __iter__ 和 __next__,还要自己存状态——挺啰嗦。生成器让你用 yield 把函数变成迭代器,状态由 python 自动保存:
def gen():
for i in range(3):
yield i * i
g = gen() # g 就是一个生成器对象(也是迭代器)
print(next(g)) # 0
print(next(g)) # 1
print(next(g)) # 4
为什么方便:yield 每次"暂停"把值交出来,下次 next() 从暂停处继续。你不用手动管下标、不用存列表,函数体就是状态机。
这是最该记住的一点,用大文件举例:
# 迭代器(但提前把 100 万个平方全算好塞进列表)—— 占内存
def squares_list(n):
return [i*i for i in range(n)]
# 生成器 —— 要一个才算一个,内存几乎为 0
def squares_gen(n):
for i in range(n):
yield i*i
for x in squares_gen(1_000_000):
if x > 100:
break
差别:列表版本先把一百万个数全造出来(几十 mb);生成器版本算到 x>100 就停,后面根本没算。这就是"懒求值"的价值——处理大文件、无限序列、流式数据时,生成器是刚需。
gen_expr = (i*i for i in range(1000000)) # 注意是 () 不是 [] print(next(gen_expr)) # 0
对照:[] 是列表推导(一次性全算),() 是生成器表达式(懒)。一个占内存,一个不占,写法只差一对括号。
迭代器和生成器都只能走一遍——走完就空了,得重新造:
g = squares_gen(3) list(g) # [0, 1, 4] list(g) # [] ← 空了!生成器已耗尽
坑点:把生成器当列表反复用,第二次永远拿到空。需要重复遍历就转成 list,或重新调用函数再造一个。
| 维度 | 可迭代对象 | 迭代器 | 生成器 |
|---|---|---|---|
能否 for | ✅ | ✅ | ✅ |
有 __next__ | ❌(需 iter() 造) | ✅ | ✅ |
| 是否"懒" | 否 | 看实现 | ✅ 一定是 |
| 写法 | list/str 等 | 手写类 | yield / () 表达式 |
| 遍历遍数 | 无限次 | 一遍 | 一遍 |
list() 或重新调用函数。yield 和 return 混用:return 在生成器里只用来结束并带值到 stopiteration,别当普通返回值。[... for ...] 改成 (... for ...),瞬间省内存。next() 时才发生。next() 超界报 stopiteration:用 for 或在 next(g, default) 给默认值兜底。一句话记住:迭代器是"会走路的对象",生成器是"用 yield 写的、懒的迭代器"。背概念不如记这句——要一个才生一个的,就是生成器。
以上就是3个例子讲清python迭代器和生成器的区别的详细内容,更多关于python迭代器和生成器的区别的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论