for循环的本质:循环所有对象,全都是使用迭代器协议。
第一部分
关于为什么要用迭代器:
优点:
1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)
2:迭代器与列表比较,迭代器是惰性计算的,更节省内存
缺点:
1:无法获取迭代器的长度,使用不如列表索引取值灵活2:一次性的,只能往后取值,不能倒着取值用以下例子示例:用索引取字典的内容: d=[1,2,3] i=0 while i < len(d): print(d[i]) i+=1其执行结果是:
1 2 3用索引取列表的内容:
d=[1,2,3] for i in range(len(d)): print(d[i])其执行结果是:
1 2 3用迭代器的方法分别取字典的值:
#用迭代器的方式取字典的内容()不依靠索引 d={"a":1,"b":2,"c":3} i=d.__iter__()#生成迭代器 #print(i.__next__())#打印内容 while True: try: print(i.__next__())#打印内容 except StopIteration: break其执行结果是:
a b c用迭代器的方法取列表里的元素:
#用迭代器的方式取列表的内容()不依靠索引 d=[1,2,3,4,5] i=d.__iter__()#生成迭代器 # print(i.__next__())#打印内容 while True: try: print(i.__next__()) except StopIteration: break其执行结果是:
1 2 3 4 5总结:
(1)、可迭代的:只要对象本身有__iter__方法,那它就是可迭代的
d={'a':1,'b':2,'c':3}
d.__iter__ #iter(d)(表示d是可迭代的)
(2)、执行对象下的__iter__方法,得到的结果就是迭代器
i=d.__iter__()(i即是迭代器)
(3)3、i.__next__()(即表示的就是执行从字典d里取值)
print(i.__next__()) print(i.__next__()) print(i.__next__())关于迭代器的使用,用以下举例: 用字典示例while循环(由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错) #由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错,故而使用下列方法可以全部打印且不报错 d={'a':1,'b':2,'c':3} i=iter(d)#即i=d._iter_() while True: try: print(next(i))#即print(i.__next__()) except StopIteration: break执行结果是:
a b c用列表示例while循环:
l=['a','b','c','d','e'] i=l.__iter__() while True: try: print(next(i))#即print(i.__next__()) except StopIteration: break执行结果是:
a b c d e用字典示例:(for循环) d={'a':1,'b':2,'c':3} d.__iter__#代表d是可迭代的 for k in d: #d.__iter__()#取字典里key的值 print(k)
其执行结果是:
a b c用集合示例(for循环) s={1,2,3,4} s.__iter__()#s是可迭代的 for i in s: print(i)
执行结果是:
1 2 3 4用文件示例,往文件里写入内容 with open('a.txt','r') as f: f.__iter__()#f是可迭代的 for line in f:#相当于执行的是print(f.__next__)并且不会报错 print(line)
执行结果是:
aaaaaa bbb cccc eee ffffff
关于迭代器,补充的有:
用列表示例,如果列表里有3个元素,故而打印4个print(next(i))会报错 l=[1,2,3] print(len(l)) i=iter(l)#l是可迭代的 print(next(i)) print(next(i)) print(next(i)) print(next(i))执行结果是:
3 1 2 3 Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/py_fullstack_s4/day23/迭代器.py", line 109, in <module> print(next(i)) StopIteration报错原因是: 因为迭代器是一次性的,只能往后取值,不能倒着取值
用列表示例,如果列表里有3个元素,print(next(i))打印3次列表里的元素,则for循环无元素可打印 l=[1,2,3] print(len(l))#输出列表l的长度 i=iter(l)#l是可迭代的 print(next(i)) print(next(i)) print(next(i)) for x in i: print(x)执行结果是:
3 1 2 3结论:for循环没有进行
用列表示例,如果列表里有3个元素,print(next(i))打印1次列表里的元素,则for循环可打印剩下的2个元素 l=[1,2,3] print(len(l))#输出列表l的长度 i=iter(l)#l是可迭代的 print(next(i)) for x in i: print(x)执行结果是:
3#由print(len(l))打印的结果 1 #由print(next(i)打印的结果 2 #由for循环打印的结果 3#由for循环打印的结果
第二部分
查看可迭代对象与迭代器对象 通过from collections import Iterable,Iterator来查看分别查看字符串、列表、元组、字典、集合、文件是否是可迭代对象与迭代器对象 s='hello'l=[1,2,3]t=(1,2,3)d={'a':1}set1={1,2,3,4}f=open('a.txt') 示例:查看是否是可迭代对象 s='hello' l=[1,2,3] t=(1,2,3) d={'a':1} set1={1,2,3,4} f=open('a.txt') # 判断是否是可迭代对象,返回Ture是可迭代的 s.__iter__() l.__iter__() t.__iter__() d.__iter__() set1.__iter__() f.__iter__() print(isinstance(s,Iterable)) print(isinstance(l,Iterable)) print(isinstance(t,Iterable)) print(isinstance(d,Iterable)) print(isinstance(set1,Iterable)) print(isinstance(f,Iterable)) # 发现都是可迭代的其执行结果是:
True True True True True True示例:判断是否是迭代器
# 判断查看是否是迭代器,返回Ture是迭代器 s='hello' l=[1,2,3] t=(1,2,3) d={'a':1} set1={1,2,3,4} f=open('a.txt') print(isinstance(s,Iterator)) print(isinstance(l,Iterator)) print(isinstance(t,Iterator)) print(isinstance(d,Iterator)) print(isinstance(set1,Iterator)) print(isinstance(f,Iterator))执行结果是:
False False False False False True返回结果是只有文件是迭代器
第三部分生成器就是一个函数,这个函数内包含有yield这个关键字关于生成器yield的返回值和函数中return的返回值有何区别:区别是:return只能返回一次函数就彻底结束了,而yield能返回多次值
yield到底有何作用:
1.yield把函数变成生成器-->迭代器2.用return返回值能返回一次,而yield返回多次3.函数在暂停以及继续下一次运行时的状态是由yield保存示例说明:
def countdown(n): print('start coutdown') while n > 0: yield n #有yield将函数变成了生成器 n-=1 g=countdown(5) print(isinstance(g,Iterator))#判断g是一个迭代器 print(g)#返回内存地址 print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))
执行结果:
True <generator object countdown at 0x0000000001E20620> start coutdown 5 4 3 2 1
转载于:https://www.cnblogs.com/xuyuanyuan123/p/6694737.html
相关资源:JAVA上百实例源码以及开源项目