迭代器和生成器

一:什么是可迭代对象?

方法一: 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))
View Code

三:迭代器的意义?

 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
View Code

六,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__())
View Code

七, 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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


posted @ 2018-02-06 17:46  扬帆起航111  阅读(153)  评论(0编辑  收藏  举报