http://www.cnblogs.com/wuyongqiang/p/6694800.html 写的很好!
迭代器是一次性的
1、之前用while循环和for迭代列表l
1
2
3
4
5
6
7
8
9
|
l = [ 'a' , 'b' , 'c' , 'd' , 'e' ] i = 0 #用while循环打印出l while i< len (l): print (l[i]) i + = 1 #用for循环打印出l for i in range ( len (l)): print (l[i]) |
2、可迭代对象(Iterable)
先了解一下可迭代对象(Iterable),可以直接作用于for循环的对象统称为可迭代对象,有两种方法判断一个对象是否为可迭代对象:一是可以使用isinstance()判断一个对对象是否是Iterable对象(再用这个方法的时候一定记得调用模块);另一种是Python内置方法中有 .__iter__ 方法,如果能引用该方法的对象都是可迭代对象(.__iter__方法调用后的执行结果就是迭代器):
1
2
3
4
5
6
7
8
9
10
11
|
from collections import Iterable print ( isinstance ([],Iterable)) # True 列表是可迭代对象 print ( isinstance ({},Iterable)) # True 字典是可迭代对象 print ( isinstance ( 'abc' ,Iterable)) # True 字符串是可迭代对象 print ( isinstance ((x for x in range ( 10 )),Iterable)) # True 生成器是可迭代对象 print ( isinstance ( 100 ,Iterable)) # False 数字不是可迭代对象<br><br> |
1
|
l = [ 'a' , 'b' , 'c' , 'd' , 'e' ]<br>l.__iter__() #能够调用__iter__说明l是可迭代对象<br>------------------------------------------<br>#重点是__iter__()函数的作用<br>l.__iter__()等同于调用iter(l)函数<br>我们把函数运行结果赋值给i即:<br>i=l.__iter__ 或者 i=iter(l)<br>此时i就是迭代器,i就是迭代器,i就是迭代器 |
3、迭代器(Iterator)
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
由定义就可以看出Iterator特性就是可以被next()调用所以判断是不是迭代器也同样有两种方法:
1
2
3
4
5
6
7
8
9
|
from collections import Iterator print ( isinstance ((x for x in range ( 10 )), Iterator)) # True 生成器是迭代器 print ( isinstance ([], Iterator)) # False 列表不是迭代器 print ( isinstance ({}, Iterator)) # False 字典不是迭代器 print ( isinstance ( 'abc' , Iterator)) # False 字符串不是迭代器<br><br> |
1
|
l = [ 'a' , 'b' , 'c' , 'd' , 'e' ]<br>l不能调用.__next__方法,所以l不是迭代器 |
4、总结可迭代对象(Iterable)与迭代器(Iterator)的区别
迭代器:
独有.__next__方法
也有.__iter__方法
迭代器.__iter__()后还是迭代器
可迭代对象:
有.__iter__方法
补充:文件句柄既能被next()函数调用又能被iter()函数调用,所以文件既是迭代器,又是可迭代对象
字符串,列表,元组,字典,集合都不是迭代器,是可迭代对象
整形不是可迭代对象,所以更不可能是迭代器
5、迭代器while循环简单举例
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
27
28
29
30
|
d = { 'a' : 1 , 'b' : 2 , 'c' : 3 } i = d.__iter__() #i=iter(d)#和上面的等式一模一样 i就是迭代器 print (i.__next__()) #等同于下面 print ( next (i)) #等同于上面 print (i.__next__()) print (i.__next__()) #因为字典中的key只有3个,所以在这里会报错,因为超出了范围 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #报错内容是StopIteration,下面就一起消除这个报错吧 d = { 'a' : 1 , 'b' : 2 , 'c' : 3 } i = d.__iter__() #这是一个iter函数,等同于iter(d) i就是迭代器 #i=iter(d)#和上面的等式一模一样 i就是迭代器 while True : try : #try...except捕捉异常,看是否出现StopIteration这个异常,如果出现执行break,相当于一个if判断 print ( next (i)) except StopIteration: break 列表的例子: l = [ 'a' , 'b' , 'c' , 'd' , 'e' ] i = l.__iter__() # i=iter(i) while True : try : #try...except捕捉异常 print ( next (i)) except StopIteration: break <br><br>文件的例子: |
f=open("a.txt","r")
i=f.__iter__()
while True:
try:
print(next(i),end="")
except StopIteration:
break
6、迭代器for循环简单举例
1
2
3
4
5
6
7
8
9
10
11
12
13
|
d = { 'a' : 1 , 'b' : 2 , 'c' : 3 } for k in d: #for循环在这里做的事可以理解为 d=d.__iter__(),牛逼! print (k) #而且for循环自动加了next()函数,自动next下一个,牛逼! #而且for循环把while循环当中的try...except所做的是给做了,牛逼! s = { 1 , 2 , 3 , 4 } #for循环列表 for i in s: print (i) with open ( "a.txt" , "r" ) as f: for line in f: print (line,end = "") |
7、for循环与while循环小结
上边的三个强大功能
不是索引的取值就是迭代器方式的取值
任何for循环能够完成的while循环都能够完成
8、为什么要用迭代器
优点:1.迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象(比如字典,集合,文件)
2.迭代器与列表相比更节省内存,是惰性计算的,时刻保持内存中只有一条在运行
缺点:1.永远无法获取迭代器的长度,使用不如列表索引取值灵活
2.迭代器是一次性的,next()只能往后取值,取完就没有了,但是for一次就搞完了
9、为什么要把文件句柄设为一个迭代器
因为Python是一门简洁的语言,列表,字符串,字典等等只能放到内存中,只有文件能永久保存,而且文件不排除有特别大的,为了避免内存炸掉把他作为一个可迭代对象,一点一点看,read应该就