迭代器和生成器
一:什么是可迭代对象?
方法一: dir(被测对象) 如果 它含有__iter__ ,那这个对象就叫做可迭代对象,遵循可迭代协议。
s = 'abc' print('__iter__' in dir(s)) print('__iter__' in dir(333))
方法二:
l = [1,2,3] from collections import Iterable print(isinstance(l,Iterable))
二:可迭代对象与迭代器的关系
可迭代对象:str list tuple dict set range
迭代器: 文件句柄
1, 可迭代对象.__iter__()就可以转化为迭代器
s = 'abc' s1 = s.__iter__() print(s1) #iterator 遵循迭代器协议# <str_iterator object at 0x00000232E83265F8>
2,迭代器的取值
迭代器取值s2 = 'abcd' s3 = s2.__iter__() print(s3.__next__()) print(s3.__next__()) print(s3.__next__()) print(s3.__next__())
3,只含有__iter__方法的数据是可迭代对象,含有__iter__方法,并且含有__next__方法的数据是迭代器。
l = [1,2,3,4] print(dir(l)) print('__iter__' in dir(l)) #True,说明列表是可迭代对象 print('__next__' in dir(l)) #False,说明列表不是迭代器 print('__iter__' in dir(range(10))) #True print('__next__' in dir(range(10))) #False,说明range是可迭代对象,但不是迭代器
4,可以通过isinstance判断其是迭代器还是可迭代对象。
l = [1,2,3] l_iter = l.__iter__() #将l变成迭代器 from collections import Iterable from collections import Iterator print(isinstance(l,Iterable)) print(isinstance(l,Iterator)) print(isinstance(l_iter,Iterator)) print(isinstance(l,list))
三:迭代器的意义?
1,迭代器节省内存.
2,迭代器惰性机制.
3,迭代器不能反复,一直向下执行.
四:for循环的机制
内部含有__iter__方法,他会将可迭代对象先转化成迭代器. ,然后在调用__next__方法. 他有异常处理的方法.
for i in [1,2,3]: print(i) l = [1,2,3] l_iter = l.__iter__() while True: try: print(l_iter.__next__()) except StopIteration: break
五:什么是生成器?
生成器的本质就是迭代器,生成器是自己用python代码写的迭代器.(1,可以用生成器函数,2,可以用各种推导式构建迭代器,3,可以通过数据转化)
1,生成器函数和生成器
def gener(): print('aaa') yield 222 print('bbb') yield 333 print('ccc') g = gener() print(g) #<generator object gener at 0x00000221830391B0> print(g.__next__()) print(g.__next__()) #打印aaa,222,bbb,333
六,return和yield的区别
return, 返回给调用者值,并结束此函数.
yiled 返回给调用者值,并将指针停留着当前位置.
def cloth(): for i in range(10000): yield '衣服%s'%i g_cloth = cloth() for i in range(50): #此处的for循环是为了控制打印的次数 print(g_cloth.__next__()) for i in range(50): #继续打印50此 print(g_cloth.__next__())
七, send和next的区别
1, send 和next功能一样
2, 给上一个yiled 整体发送一个值
3,send不能给最后一个yield发送值
4,获取第一个值的时候,不能用send 只能用next
def gener(): yield 222 count = yield 333 print(count) yield 'aaa' yield 'bbb' g = gener() print(g.__next__()) print(g.send(None)) print(g.send('AAAA')) print(g.send('wwwwww')) #最后打印的结果为:222,333,AAAA,aaa,bbb