可迭代对象
- 从集合的第一个元素开始访问,直到所有的元素被访问完结束,即可以被for循坏遍历
- 需要实现__iter__ 或者 __getitem__方法
from collections.abc import Iterator,Iterable
class testIter():
def __init__(self):
pass
def __iter__(self):
pass
print(isinstance(testIter(),Iterable)) #输出 True ,说明时可迭代对象
print(isinstance(testIter(),Iterator)) #输出 False ,说明不是迭代器
迭代器
- 遵循迭代器协议的对象
- 迭代器协议:实现__iter__ 和 __next__方法,方法放回迭代器本身,next()方法返回容器的下一个元素
- 迭代器如果没有后续元素,访问时会抛出StopIteration异常,只能往前访问不能后退
- 迭代器是一个可以记住遍历的位置的对象
- 使用iter()可以获取迭代器对象
迭代器实现
- 对可迭代对象使用,iter方法
from collections.abc import Iterator,Iterable
print(isinstance(iter(str()),Iterable)) #输出True
print(isinstance(iter(str()),Iterator)) #输出True
- 实现__iter__和__next__方法,实现为迭代器
from collections.abc import Iterator,Iterable
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
var=testIter('abc')
print(isinstance(var,Iterable)) #输出 True ,说明时可迭代对象
print(isinstance(var,Iterator)) #输出 True ,说明是迭代器
print(isinstance(str(),Iterable)) #输出True
print(isinstance(str(),Iterator)) #输出False
next方法依次访问元素
访问testIter(‘abc’)迭代器
print(next(var)) #输出 c
print(next(var)) #输出 b
print(next(var)) #输出 a
print(next(l)) #报异常 StopIteration
#或者通过for循环访问
for i in var:
print(i)
生成器
- 是一种特殊的迭代器
- 可以使用next和send取值,不同的是,send在获取下一个元素时可以同时向生成器传递一个值,next和send(None)等同
生成器实现
使用yeild关键字
yeild:与return功能相似,会返回一个值,但是遇到yeild的时候函数会暂停并保存当前的运行信息,下次执行next/send方法时会继续执行
生成器优点:不需要将所有数据一次性都加载到内存中,对于需要的数据才进行访问
def testGene(n):
for i in range(n):
if i % 2 == 0:
yield str(i) * 5
print('abc')
g=testGene(10)
print(next(g)) #执行这一步输出 00000
print(next(g)) #执行这一步输出 abc
# 22222 可以看出第一次执行到yield时就停止了,再次调用next方法时,继续执行print('abc')
- next和send方法的区别
还是以上例子通过send方法调用
print(g.send(None)) #第一次访问,send的参数必须是None 输出 00000
print(g.send('send1')) #执行这一步输出 abc
# 22222
print(g.send('send2')) #执行这一步输出 abc
# 44444
可以看出send传递的值没有生效,需要修改一下生成器的实现
def testGene(n):
for i in range(n):
if i % 2 == 0:
x=yield str(i) * 5 #接收send传递的值
yield x
print('abc')
g=testGene(10)
print(g.send(None)) #输出00000 (执行到第一个yield暂停,并返回00000)
print(g.send('send1')) #输出send1 (继续执行x='send1',遇到第二个yield,并返回'send1')
print(g.send('send2')) #执行这一步输出 abc (继续执行print,遇到生成器中的第一个yield,并返回22222
# 22222
print(g.send('send3')) #输出send3 (执行x='send3',遇到生成器中的yield并返回send3
print(next(g)) #执行这一步输出 abc (继续执行print,遇到生成器中的第一个yield,并返回44444
# 44444
使用生成器表达式
区别列表推导式,列表推导式使用的[],生成器使用的()
from collections.abc import Iterator,Iterable,Generator
var=(x for x in range(10) if x%2==0)
print(isinstance(var,Iterator)) # 输出True
print(isinstance(var,Generator)) # 输出True,说明var时一个生成器