迭代器与生成器

回眸只為那壹抹淺笑 提交于 2019-11-30 12:10:31

实现迭代器

  1. 要实现迭代器,只要实现如下两个方法即可:
  • __iter__(self):该方法返回一个迭代器(iterator),迭代器必须包含一个__next__()方法,该方法返回迭代器的下一个元素。
  • __reversed__(self):该方法主要为内建的reversed()反转函数提供支持,当程序调用reversed()函数对指定迭代器执行反转时,实际上是由该方法实现的。(如果不需要让迭代器反转迭代,这个方法也可以不用实现)

示例代码如下:

# 定义一个斐波那契数列的迭代器
class Fibs(object):
	def __init__(self, len):
		self.first = 0
		self.sec = 1
		self.__len = len
	def __next__(self):
    # 迭代器所需的__next__方法
		if self.__len == 0:
			raise StopIteration
		self.first, self.sec = self.sec, self.first + self.sec
		self.__len -= 1
		return self.first
	def __iter__(self):
    # 定义__iter__方法,该方法返回迭代器
		return self
        
fibs = Fibs(10) # 创建Fibs对象
print(next(fibs) ## 1
print(next(fibs) ## 1
for i in fibs:
	print(i, end=' ')
## 3 5 8 13 21 34 55 
  1. 也可以通过内置的iter()函数将列表、元组等转换成迭代器。
my_iter = iter([1,'hi',3])
print(my_iter.__next__()) # 1
rint(next(my_iter)) # hi

实现生成器

1. 生成器与迭代器

相同点:都会提供__next__()方法,可用next()函数来获取生成器的下一个值,也可以使用for循环来遍历生成器
区别点:迭代器通常是先定义一个迭代器类,然后通过创建实例来创建迭代器;而生成器则是先定义一个包含yield语句的函数,然后通过调用该函数来创建生成器。

2.创建生成器
  1. 使用生成器定义一个差值递增的数列,实例代码如下:
def test(val,step):
	print('--start--')
	cur = 0
	for i in range(val):
		cur += i*step
		yield cur
        
t = test(10,2)
print(next(t))
## --start--
## 0
print(next(t))
## 2

yield cur语句的作用有两点:
* 每次返回一个值,有点类似于return语句
* 冻结执行,程序每次执行到yield语句时就会被暂停

调用yield语句的函数并不会立即执行,它只是返回一个生成器。只有当程序通过next()函数调用生成器或遍历生成器时,函数才会真正执行。

  1. 两种方式来创建生成器

    • 使用for循环的生成器推导公式
    • 调用带有yield语句的生成器函数
3.生成器的send()方法
  1. 为了实现生成器与“外部程序”动态地交换数据,需要借助于生成器的send()方法。
  2. 该方法与next()函数的功能非常相似,它们都用于获取生成器所生成的下一个值并将生成器“冻结”在yield语句处;但send()方法可以接收一个参数,该参数值会被发送给生成器函数。
  3. 在生成器函数内部,程序可通过yield表达式来获取send()方法所发送的值—这意味着此时程序应该使用一个变量来接收yield语句的值。
  4. 只有等生成器被“冻结”之后,外部程序才能使用send()方法向生成器发送数据。获取生成器第一次所生成的值,应该使用next()函数;如果非要使用send()方法获取生成器第一次所生成的值,也不能向生成器发送数据,只能为该方法传入None参数。

示例代码如下:

>>> def square_gen(val):
	i = 0
	out_val = None
	while True:
		out_val = (yield out_val**2) if out_val is not None else (yield i**2)
		if out_val is not None:
			print("-----%d" %out_val)
		i += 1

		
>>> sg = square_gen(5)
>>> print(sg.send(None))
0
>>> print(next(sg))
1
>>> print("====")
====
>>> print(sg.send(9))
-----9
81
>>> print(next(sg))
9
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!