可迭代对象:
迭代协议:只要对象内部定义了__iter__方法就实现了迭代协议;能被for循环的对象,都是可迭代对象拥有__iter__方法
例子:
s ="2222"
li = [1, 2, 3.5, 2]
dic = {'a':1}
print(s.__iter__())
print(li.__iter__())
print(dic.__iter__())
迭代器:
1、对象实现迭代协议
2、对象实现了__next__方法
注:可迭代对象可以通过 iter()方法转换为迭代器
例子:将可迭代对象,转换为迭代器
from typingimport Iterable, Iterator, Generator
li = [1, 2, 3.5, 2]
liter =iter(li) #可迭代对象转换为迭代器
print(isinstance(liter, Iterable))
迭代器每次只会取一个值,不会一下子全部返回与迭代器相比占用的内存较小:
print(next(liter))
注意当值全部取完后会抱一个错误信息:
意思是值都取完了
生成器:
生成器是一种特殊的迭代器
注意:生成器比迭代器多了三个方法
生成器比迭代器多了三个方法,close、send、throw
生成器属于迭代器,迭代器属于可迭代对象
g = (ifor iin range(100))
print(isinstance(g, Generator))
生成器取值:print(next(g))
close:关闭生成器
print(g.close())
print(next(g))
关闭生成器后就无法在获取值,错误信息与取值完后是一样的信息
send:与生成器内部数据进行交互(调用该方法前提是,先使用一次next生成一条数据)
def gen():
print('----start------')
for iin range(10):
s =yield i
print(s)
print('-----end--------{}'.format(i))
g = gen()
res=g.send(88)
print(res)
输出结果是 88
send 改变数据内部生成的规则
使用了yelid函数,当函数中有使用yield,那么这个函数就不再是一个普通的函数了,调用执行的时候不会直接执行会自动返回一个生成器对象
变量s 接收的是通过send传入的值
throw: 在生成器内部主动引发一个异常,参数:异常类型 异常信息
g.throw(NameError, '异常信息')