1. 什么是迭代工具:
能够从左到右扫描对象的方法,比如: for循环,列表推导,in成员关系测试,以及内置函数map等。
2. 可迭代对象与迭代器对象:
(1)可迭代对象:迭代的被调用对象,其__iter__方法被iter函数所调用,简单来说,有__iter__方法的对象,就是可迭代对象。
(2)迭代器对象:可迭代对象的返回结果,在迭代过程中实际提供值的对象。它的__next__方法被next运行,并在结束时触发StopIteration 异常。可以理解为,有__next__的对象就是迭代器对象。
3. 从文件迭代器了解迭代协议:
逐行读取文本文件的最佳方式就是根本不要去读取;应该让for循环在每轮迭代中自动调用 next,从而前进到下一行,文件对象的迭代器会随着读取的进行,自动载入下一行。
for line in open("script2.py"):
print(line.upper(), end='')
上面是最简单的写法,运行最快而且节省内存,相同效果的原始方式,是以for循环调用文件的readline()方法,将文件内容加载到内存,并形成行字符串的列表 。
for line in open('script2.py').readline():
print(line.upper(), end='')
这个方法会耗用很多的内存,一次性把整个文件加载进内存中,如果文件太大,内存就不够用了。
while循环比基于迭代器的for循环运行得更慢,因为迭代器在Python内部是以C语言的速度运行的,而while循环版本则是通过Python 虚拟机运行Python字节码的。任何时候,我们把python代码换成C程序代码,速度都会有所提升的。
f = open('script2.py')
while True:
line = f.readline()
if not line: break
print(line.upper(), end='')
4. next() 方法
Python3 提供了一个内置函数 next(),给定一个迭代器对象 X, 调用 next(X)等同于3.x版本中 的X.__next__(),但其实next()更简单可移植性更好。
f = open('script2.py')
print(f.__next__()) # 'import sys\n'
f = open('script2.py')
print(f) # 'import sys\n'
5. iter()方法
for循环开始时,可以把可迭代对象传入内置函数 iter,并由此拿到一个迭代器,而iter返回的迭代器对象有着所需要的next方法。
iter函数与next和__next__很象,在它内部调用了__iter__方法。
6. 迭代协议总结:
所有带有 __next__ 方法的对象会前进到下一个结果,而当到达一系列结果的末尾时,__next__ 会引发 StopIteration 异常,这种对象在 python 中也被称为迭代器。所有迭代工具内部工作起来都是在每次迭代中调用 __next__ ,并且通过捕捉 StopIteration 异常来确定何时离开。
除了用迭代工具进行迭代,也可以手动迭代,比如用 iter() 和 next()函数。
调用 next(X) 相当于调用 X.__next__();
调用 iter(X),返回一个迭代对象,迭代对象有着所需要的 next方法。
lst = [1, 2, 3]
for i in iter(lst):
print(i)