08 python迭代器和生成器
python中的迭代协议
什么是迭代器?
迭代器是访问集合内部元素的一种方式,一般用于遍历数据
迭代器和用下标的访问方式不一样,也就是说迭代器是不能返回数据的,迭代器提供了一种惰性方式产生数据
可迭代实质上是由__iter__来实现的
迭代器必须要同时有__iter__和__next__魔法函数
1 2 3 4 5 | from collections.abc import Iterable, Iterator a = [ 1 , 2 ] print ( isinstance (a, Iterable)) print ( isinstance (a, Iterator)) |
输出结果如下

什么是迭代器和可迭代对象
可迭代对象 内部实现了 __iter__方法 可以用于遍历
迭代器 内部实现了 __iter__和__next__方法 可以用于遍历和next()取值
把一个可迭代对象编程迭代器,可以使用iter(可迭代对象)
1 2 | a = [ 1 , 2 ] iter_rator = iter (a) |
自定义一个迭代器
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 | class MyIterator: def __init__( self , employee_list): self .iter_list = employee_list self .index = 0 def __iter__( self ): return self def __next__( self ): #真正返回迭代值的逻辑 try : word = self .iter_list[ self .index] except IndexError: raise StopIteration self .index + = 1 return word if __name__ = = "__main__" : company = MyIterator([ "tom" , "bob" , "jane" ]) print ( next (company)) for item in company: print (item) |
输出结果如下
生成器函数的使用
生成器函数,函数里只要有yield关键字
1 2 3 4 5 6 7 8 9 10 | #生成器函数,函数里只要有yield关键字 def gen_func(): yield 1 yield 2 yield 3 gen = gen_func() print ( next (gen)) for item in gen: print (item) |
输出结果如下
递归实现 斐波那契求值
1 2 3 4 5 6 7 8 | def fib(index): if index < = 2 : return 1 else : return fib(index - 1 ) + fib(index - 2 ) if __name__ = = '__main__' : print (fib( 8 )) |
输出结果如下
生成器实现斐波那契
1 2 3 4 5 6 7 8 9 10 11 12 | def gen_fib(index): n,a,b = 0 , 0 , 1 while n<index: yield b a,b = b, a + b n + = 1 if __name__ = = '__main__' : gen_fib = gen_fib( 10 ) for value in gen_fib: print (value) |
打印结果如下
生成器在UserList中的应用
查看UserList的源码
from collections import UserList
可以看到每次遍历的时候都会通过yield返回一个值
生成器如何读取大文件
假如有一个500G的文件,我们想要读取它,如果它是一行一行的话我们可以使用for循环一行一行的读
这里的一个500G的文件是在一行,这时候我们可以用生成器来读取
input.text
1 | Prior to beginning tutoring sessions{|}, I ask new students to fill{|} out a brief self - assessment{|} where they rate their{|} understanding of various Python concepts. Some topics ( "control flow with if/else" or "defining and using functions" ) are understood by a majority of students before ever beginning tutoring. There are a handful of topics, however, that almost all {|} students report having no knowledge or very limited understanding of. Of these |
生成器读取大文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #500G, 特殊 一行 def myreadlines(f, newline): buf = "" # 缓存,用来保存生成器一次返回的数据 while True : while newline in buf: pos = buf.index(newline) yield buf[:pos] buf = buf[pos + len (newline):] # 获取的是满足条件的一行+ {|}后面的内容 chunk = f.read( 4096 ) if not chunk: #说明已经读到了文件结尾 yield buf break buf + = chunk with open ( "input.txt" ) as f: for line in myreadlines(f, "{|}" ): print (line) |
输出结果如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理