python中生成器和迭代器以及可迭代对象的区别

北战南征 提交于 2019-11-26 10:34:10

先简单的总结一下三种之间的关系:

生成器和迭代器都是可迭代对象, 而生成器是一类特殊的迭代器.
对于生成器和迭代器我们都可以使用next()函数来获取其下一个返回值,
当然也可以使用for...in...来获取他们的返回值(iter返回对象本身),
iter函数: 获取可迭代对象身上的迭代器, 会调用可迭代对象身上的iter的方法 
next函数: 获取迭代器中的下一个值,会调用迭代器对象身上的next的方法
所以先调用可迭代对象的iter方法获得迭代器
就可以使用迭代器的next方法

然后在进行分别说明:

可迭代对象: 在python中通俗的来讲就是能够通过for...in...这类语句迭代读取一条数据供我们使用的对象就称之为可迭代对象(Iterable)。
           例如列表(list),元组(tuple)等,我们还可以通过isinstance(obj, Iterable)来判断一个对象是不是可迭代对象.
           如果对象是可迭代对象则,isinstance的结果返回True

例:
	from collections import Iterable
	obj = ['a','b',1,2]
	isinstance(obj, Iterable)
	# True
	
	obj_1 = {3,5,6,7,2}
	isinstance(obj_1, Iterable)
	# True
———————————————————————————————————————————————————————————————
迭代器:  迭代器是一种对象,它能够记录可迭代对象每次迭代的数据的地址,
	     以便每次迭代都可以返回下一条数据.在python中只要一个类实现了__iter__方法和__next__方法,
         那么这个类的实例对象就是一个迭代器.
         我们可以通过isinstance(obj_1, Iterator)来判断一个对象是不是可迭代对象,如果是则isinstance返回True.
         生成器是特殊的迭代器
         
例:
	from collections import Iterator
	class Desc(object):
		def __iter__(self):
			return self
		
		def __next__(self):
			value = self.curr
	
	def main():
		print(isinstance(Desc(), Iterator))
		self.curr += self.prev
		self.prev = value
		return value
	
	if __name__ == '__main__':
		main()
	
	上面代码执行的结果为 True

生成器(generator)和迭代器的实现方式不一样,生成器可以通过生成器推导式或yield关键字来实现,两种方式如下:

gen = (i for i in range(10000))
print(gen)
print(type(gen))
# <generator object <genexpr> at 0x00000000035DE200>
# <class 'generator'>

例:
	def fibonacci(n):
		current = 0
		num1, num2 = 0,1
		while current < n:
			num = num1
			num1,num2 = num2,num1 + num2
			current += 1
			yield num
	
	F = fibonacci(5)
	f = next(F)
	print(f)
	# 0
	f = next(F)
	print(f)
	# 1
	f = next(F)
	print(f)
	# 1

对于上面这种使用yield方式创建的生成器,
当我们next()去调用的时候, 函数fib会返回yield后面的值,并将函数fib挂起,
当再次使用next()去调用的时候,函数fib接下来的逻辑(即while)会被继续执行,
当while循环完之后如果在去使用next()调用函数fib就会抛出StopIteration  异常,而不会返回done,
如果想获得返回值,则必须将异常捕获.(try)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!