迭代器和生成器

Iterator(迭代器)

迭代器是访问集合元素的一种方式,是一个可以记住当前访问位置的对象

  1. 将对象转成迭代器使用iter()

    a = [1,2,3]
    iter(a)
    next(a)
    >>> 1
    
  2. 迭代器可以使用next()进行遍历,当全部遍历完之后,就会抛出StopIteration异常

  3. 定义可迭代的类,两个关键要素:__iter____next__,通常使用的for...in...就是使用的这两个要素

    class Reverse:
        def __init__(self,data):
            self.data = data
            self.index = len(data)
            
        def __iter__(self):
            return self
        
        def __next__(self):
            if self.index == 0:
                raise StopIteration
            self.index = self.inedex -1
            return self.data[self.index]
        
    rev = Reverse([1,2,3])
    next(rev)
    >>> 3
    for i in rev:
        print(i)
        
    """
    2
    1
    """
    
  4. 比起列表(list)来说,迭代器最大的优势就是延迟计算按需使用,从而提高开发体验和运行效率,也能节省内存,以至于在Python 3中map,filter等操作返回的不再是列表而是迭代器

Generator(生成器)

使用了yield的函数是生成器

生成器是一个返回迭代器的函数,同时它就是迭代器

每次调用next()在生成器上时,都会从之前访问的位置继续开始

这个特点常用于流水线异步,比如:

播放一段视频,你突然有事走开,需要暂停视频,等你忙完回来,在从暂停位置开始看起,而不是从视频的开头开始,重头看起

创建生成器

  1. 和创建列表类似,但是不用中括号[]而是用括号()

    gen = (x for i in range(10))
    # ()生成器,[]列表,{}集合或者键值对
    # 遍历
    while True:
        try:
            print(next(gen))
        except StopIteration:
            break
            
    ------------------------------
    
    for i in gen:
        print(i)
    

创建生成器函数

# 函数有了yield之后,函数名+()就变成了生成器
# return在生成器中代表生成器的中止,直接报错
# next的作用是唤醒并继续执行
# send的作用是唤醒并继续执行,发送一个信息到生成器内部
'''生成器'''
 
def coro():
    say_hello = yield 'hello'	# 第一次返回的值是'hello'但是没有赋值给变量say_hello
    							# 第二次将发送的值传给了变量say_hello,say_hello='world',继续往下执行
    yield say_hello

c = coro()	# 生成协程,生成协程后的第一步是c.send(None)或者next(c)
type(c)
print(next(c)) # 或者使用send(None),next(c)=c.send(None)
print(c.send('world'))
posted @ 2021-09-10 17:03  注入灵魂  阅读(51)  评论(0)    收藏  举报