08 python迭代器和生成器
python中的迭代协议
什么是迭代器?
迭代器是访问集合内部元素的一种方式,一般用于遍历数据
迭代器和用下标的访问方式不一样,也就是说迭代器是不能返回数据的,迭代器提供了一种惰性方式产生数据
可迭代实质上是由__iter__来实现的
迭代器必须要同时有__iter__和__next__魔法函数
from collections.abc import Iterable, Iterator a = [1, 2] print(isinstance(a, Iterable)) print(isinstance(a, Iterator))
输出结果如下
什么是迭代器和可迭代对象
可迭代对象 内部实现了 __iter__方法 可以用于遍历
迭代器 内部实现了 __iter__和__next__方法 可以用于遍历和next()取值
把一个可迭代对象编程迭代器,可以使用iter(可迭代对象)
a = [1, 2] iter_rator = iter(a)
自定义一个迭代器
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关键字
#生成器函数,函数里只要有yield关键字
def gen_func():
yield 1
yield 2
yield 3
gen = gen_func()
print(next(gen))
for item in gen:
print(item)
输出结果如下

递归实现 斐波那契求值
def fib(index):
if index <= 2:
return 1
else:
return fib(index-1) + fib(index-2)
if __name__ == '__main__':
print(fib(8))
输出结果如下

生成器实现斐波那契
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
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
生成器读取大文件
#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)
输出结果如下


浙公网安备 33010602011771号