迭代器:
迭代器是一个更抽象的概念,任何对象,如果它的类有next方法和iter方法返回自己本身。对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。
在后台for语句对容器对象调用iter()函数,iter()是python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,
next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIteration异常。
a = iter(range(10))
print(next(a))
生成器:
生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)。
yield就是return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始
区别:
生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当生成器终结时,还会自动抛出StopIteration异常
1、共同点
生成器是一种特殊的迭代器
2、不同点
a、语法上
迭代器可以通过 iter() 内置函数创建
生成器是通过函数的形式中调用 yield 或()的形式创建的
b、用法上
迭代器在调用next()函数或for循环中,所有值被返回,没有其他过程或说动作
生成器在调用next()函数或for循环中,所有值被返回,记录过程被执行的位置
生成器表达式和列表推导式的区别
1.列表推导式比较耗内存一次性加载,生成器表达式几乎不占内存,使用的时候才分配和使用内存
2.得到的值不一样 列表推导式得到的是一个列表,生成器表达式获取的是一个生成器
""" 19、迭代器(iterator) a = iter(range(10)) #迭代器类似于for循环,具有__iter__()和next()方法 print(next(a)) 20、生成器(generator) 生成器是一种特殊的迭代器,具迭代器特性,还具有有惰性,每次你去访问就给你返回一个值,不会一次性全部遍历出来 yield生成器,yield相当于return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始 a = [i for i in range(10)] #返回列表 b = iter(range(10)) #返回了一个迭代器iterator c = (i for i in range(10)) #返回了一个可迭代的generator (生成器)对象 print(type(a),b.__iter__(),c.__iter__()) print(next(b),list(b)) print(next(c),list(c)) """ #迭代器 b = iter(range(10)) print(b.__iter__()) print(b.__next__()) print(next(b),list(b)) #自定义迭代器 class Range(): def __init__(self,start ,stop ,step): self.start = start self.stop = stop self.step = step def __iter__(self): return self def __next__(self): if self.start>self.stop: raise Exception('结束迭代') next_item = self.start self.start = self.start+self.step return next_item ra = Range(1,10,1) print(ra.__iter__()) print(ra.__next__()) print(next(ra)) #生成器 d = (i for i in range(10)) #返回了一个可迭代的generator (生成器)对象 def gen(): #返回了一个可迭代的generator (生成器)对象 for i in range(10): yield i e = gen() print(d.__iter__(),e.__iter__()) print(next(d),list(d)) print(next(e),list(e))