python的迭代器和生成器

迭代器

我们把可以通过for…in…这类语句迭代读取一条数据供我们使用的对象称之为可迭代对象(Iterable)。
判断一个对象是否是可迭代对象,利用isinstacnce()方法
python的迭代器和生成器_第1张图片
在可迭代对象中记录每次迭代位置的是迭代器,可迭代对象通过__iter__方法提供一个迭代器在迭代一个可迭代对象时,实际是获取该对象的迭代器,然后通过这个迭代器来获取可迭代对象中的每一个数据。
即,一个具备了__iter__方法的对象,就是一个可迭代的对象

list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据

代码如下:

class Fibonacci(object):

	def __init__(self, all_num):

		self.all_num = all_num
		self.current_num = 0
		self.a = 0
		self.b = 1


	def __iter__(self):

		return self

	def __next__(self):

		if self.current_num < self.all_num:

			ret = self.a

			self.a, self.b = self.b, self.a + self.b

			self.current_num += 1

			return ret
		else:
			raise StopIteration

fibo = Fibonacci(10)

for num in fibo:

	print(num)

生成器

生成器是一类特殊的迭代器。

下述文字是引用:
在使用生成器实现的方式中,我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现,但是将每次迭代返回数值的return换成了yield,此时新定义的函数便不再是函数,而是一个生成器了。简单来说:只要在def中有yield关键字的 就称为 生成器

利用函数来实现生成器:
代码如下:

def create_num(all_num):

	print("-----1-----")

	a, b = 0, 1
	current_num = 0

	while current_num < all_num:
		print("-----2-----")

		yield a

		print("-----3-----")

		a, b = b, a + b
		current_num += 1
		
		print("-----4-----")

obj = create_num(10)

ret = next(obj)

print(ret)

ret = next(obj)
print(ret)

上述代码的运行结果图:
python的迭代器和生成器_第2张图片
分析:
因为生成器也是迭代器,所以我们用next方法来获取每次生成的值。
第一次运行时候运行到yield后停止,然后yield 后的值作为next获取到的值,所以输出0;之后程序在yield处停止,直到下次调用next函数。

关键:

  1. 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
  2. yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
    生成器实现斐波那契数列:
    代码如下:

def fib(n):

	current = 0

	num1, num2 = 0, 1

	while current < n:
		
		num = num1
		num1, num2 = num2, num1 + num2
		current += 1
		yield num

	return 'done'


g = fib(5)

while True:

	try:

		x = next(g)
		print("value:%d"%x)

	except StopIteration as e:

		print("生成器返回值:%s"%e.value)
		break

上述代码的输出结果:
python的迭代器和生成器_第3张图片
上述代码的分析:
其中,next函数取不到值的时候会引发StopIteration异常,因此捕获异常,最后的返回值为生成器函数的return 值。

总结:
迭代器和生成器都可以是保存生成数据生成的代码,在需要的时候再进行生成,减少占用空间,生成器相比迭代器更为方便。

原因如下:(参考自视频教案)
利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。生成器是一类特殊的迭代器。

参考:
https://www.bilibili.com/video/BV1uJ411Y7uH?p=40

你可能感兴趣的:(python高级编程)