1.生成器
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
- 延迟计算、惰性求值
- 节省内存,高效
- 缺点:无法随机存取
生成器(Generator) 生成器会产生一个对象,而不是一个列表
1.1yield表达式
#通过函数和yield关键字生成
#使用了 yield 的函数被称为生成器(generator)
#yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行
def test(n):
for i in range(1,n + 1):
yield i
#print(i)
#得到生成器
result = test(10)
print(result)
#可以使用next函数获取下一个值
print(next(result))
#生成器只能遍历一次, 所以下面不会有任何输出
for x in result:
print(x)
#可以这样遍历
for x in test(10):
print(x)
1.2生成器表达式
生成器【Generator】生成器会产生一个可迭代对象,而不是一个列表。生成器表达式很类似列表生成式:
(表达式 for var in 可迭代对象)
#将列表生成式中的[]替换成()
ge = (x for x in range(1,6))
print(ge,type(ge))
#生成器需要通过next()方法获取数据,调用一次则返回一个数据
print(next(ge))
print(next(ge))
print(next(ge))
print(next(ge))
print(next(ge))
#注意:如果通过next函数获取生成器中的数据,当数据取完之后,
#将不能再调用next函数,否则出现StopIteration
#print(next(ge)) #StopIteration
#生成器主要通过for-in的方式进行遍历
for x in ge:
print(x,end=' ')
2.迭代器
2.1 迭代对象
可以直接作用于for-in循环的数据类型都被称为可迭代对象(Iterable),可以使用isinstance()判断一个对象是否是可迭代对象,可以直接作用于for-in循环的数据类型:
- 数据结构:list、set、tuple、dict、string
- generator【生成器】【(),函数结合yield】
#引入 from collection import Iterable
from collections import Iterable
print(isinstance("",Iterable))#True
print(isinstance({},Iterable))#True
print(isinstance((),Iterable))#True
print(isinstance(1,Iterable))#False
2.2 迭代器
迭代器不但可以作用于for-in循环,还可以使用next()函数将其中的元素获取出来,当获取完最后一个元素之后,当再次调用next方法,则会出现StopIteration错误,表示无法继续返回一个值。可以使用isinstance()判断一个对象是否是迭代器。迭代器的类型是Iterator
from collections import Iterator,Iterable
print(isinstance([],Iterator)) #False
print(isinstance((),Iterator)) #False
print(isinstance({},Iterator)) #False
print(isinstance("",Iterator)) #False
print(isinstance((x for x in range(0,6)),Iterator)) #True 生成器是迭代器
print(isinstance((x for x in range(0,6)),Iterable)) #True 生成器也是迭代对象
结论:list、set、tuple、dict、string是可迭代对象,但是,不是迭代器,只有生成器才是迭代器
2.3 将迭代对象转换为迭代器
迭代器一定是可迭代对象,但是,可迭代对象不一定是迭代器
iter():将可迭代对象转化为迭代器【主要针对list、set、tuple、dict、string】
print(isinstance(iter([]),Iterator)) #True
print(isinstance(iter(()),Iterator)) #True
print(isinstance(iter({}),Iterator)) #True
print(isinstance(iter(""),Iterator)) #True
l2 = iter(l1) #将列表转换为迭代器
print(next(l2)) #使用next获取迭代器中的元素
while True:
try:
print(next(l2)) #可能出问题的代码放到try块中
except StopIteration: #捕获异常
break #终止循环