函数之迭代器、生成器
一、迭代器 (iterator)
1、for循环:对象--->(str list tuple dict set 文件句柄 range)
Python中的for循环执行机制:
for循环执行的是一个可迭代对象(iterable),
1、内部含有--
l = [1,2,3,4] for i in l: print(i) 1 2 3 4
我们用while循环来实现一个for循环的功能:
l = [1,2,3] l_iter = l.__iter__() while 1: try: print(l_iter.__next__()) except StopIteration: break 1 2 3
总结一下:for循环的执行机制:
1、iter的方法,他将可迭代对象转化为迭代器
2、再调用—next 方法
3、他有异常处理的方法
2、迭代器认知
什么是可迭代对象:遵循可迭代协议
PS :可迭代协议:
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法
如何判断是否是可迭代对象?
方法一、dir(被测试对象)输出结果中含有—iter—则他是可迭代对象
a = 'abc' print(dir(a))-----a 的所有用法 print('__iter__'in dir(a)) #Ture
方法二、isinstance 判定
from collections import Iterable from collections import Iterator l = [1,2,3,4] print(isinstance(l,Iterable)) print(isinstance(l,Iterator)) Ture False
可迭代对象与迭代器之间的转换:iterable -----> iterator
可迭代对象.__iter__() ---> #迭代器 # a = 'alex' # b = a.__iter__()
迭代器取值:
s1 = 'abcd' s2 = s1.__iter__() print(s2.__next__()) print(s2.__next__()) print(s2.__next__()) print(s2.__next__()) a b c d # 迭代器.__next__()
迭代器与可迭代对象的区别:
s1 = 'abcd' s2 = s1.__iter__() print('__iter__'in dir(s1)) #Ture print('__iter__'in dir(s2)) #Ture print('__next__'in dir(s1)) #False print('__next__'in dir(s2)) #Ture
** 只含有__iter__方法的数据是可迭代对象,含有__iter__方法并含有__next__方法的数据是迭代器。
迭代器的意义:
1、迭代器节省内存
2、迭代器有惰性机制
3、迭代器不能反复,需要一直执行下去
PS:range()-----是可迭代对象,不是迭代器
print('__next__' in dir(range(10))) #查看'__next__'是不是在range()方法执行之后内部是否有__next__ print('__iter__' in dir(range(10))) #查看'__next__'是不是在range()方法执行之后内部是否有__next__ from collections import Iterator print(isinstance(range(100000000),Iterator)) #验证range执行之后得到的结果不是一个迭代器
二、生成器 (generator)
生成器本质上是迭代器,生成器是自己用Python代码写的迭代器。
# 1,可以用生成器函数
# 2,可以用各种推导式构建迭代器.
# 3,可以通过数据转化.
生成器函数
def gener(): print('aaa') yield 222 print('bbb') yield 333 print('ccc') g = gener() print(g) # <generator object gener at 0x0000000002864A98> 生成器对象 print(g.__next__()) # aaa 222 print(g.__next__()) # bbb # 333
return yield 区别
return 返回给调用者值,并结束此函数.
yiled 返回给调用者值,并将指针停留着当前位置.
send 用法
1,send 和next功能一样
2, 给上一个yiled 整体发送一个值
send不能给最后一个yield发送值
获取第一个值的时候,不能用send 只能用next
def gener(): yield 222 count = yield 333 print('-------->',count) yield 'aaa' yield 'bbb' g = gener()
print(g.__next__())
print(g.__next__())
print(g.send('AAAA'))
print(g.__next__())
输出:
222
333
--------> AAAA
aaa
bbb