函数----迭代器和生成器

  • 迭代器

  1. 迭代器协议:对象需要提供__next__方法,他要么返回迭代器下一项,要么引起StopIteration异常
  2. 可迭代对象:对象内置有__iter__,实现迭代器协议的对象
  3. 迭代器对象:对象除了内置有 __iter__,还有__next__,可不断返回下一项或者异常的对象。

由上述可知,迭代器对象是可迭代对象的子集。

  • 迭代器内部机制举例:
num = [1,2,3,4,5]
for i in num:
    print(i)

num是一个可迭代对象,在for循环内部,首先num会调用__iter__方法,将列表变为迭代器对象,不断调用__next__返回取到的值。

  • 使用while模拟for循环
num = [1,2,3,4,5]
num = num.__iter__()
while True:
    try:
        print(num.__next__())
    except StopIteration:
        break
        
  • 自定义迭代器对象

在每一种数据类型对象中,如果有一个__iter__()方法,数据类型变为可迭代。

class  F(obj):
    def __init__(self,n):
        self.n = n
    def __iter__(self):
        print("生成迭代器对象")
        return self
    def __next__(self):
        if self.n >10:
            raise StopIteration("迭代结束")
        self.n += 1
        return self.n    
  • 迭代器的用法
num = [ 1,2,3,34,5]

num = num.__iter__()#将可迭代对象转为迭代器对象
num.__next__()#调用next,返回取得的值
  • 迭代器对象的好处;

1.节约空间,需要时再生成

2.不依赖索引迭代

举例

#对于序列可以使用索引遍历序列中每个值
names = ["lian","zong","sheng"]
index=0
while index<len(names):
    print(lis2[index])
    index+=1
#对于非序列,无法根据索引迭代,此时则需要使用到迭代器
names = {"lian","zong","sheng"}

names = names.__iter__()
while index<len(names):
    print(lis2[index])
    index+=1
  • 生成器

  • 生成器可分为生成器表达式,和带有yield的生成函数
  • 生成器表达式包含了三元表达式和列表生成式
  • 生成器表达式

  1. 三元表达式

格式:在x条件下,如果y成立,则取值z,否则k

例子:

l = "beautiful"
h = 175 if l = "ugly" else 155 #如果l是ugly,那么h取值175,否则155

   2.列表生成式

格式:前面是生成规则,后面是初始化元素,再后面是判断条件

举例:

l = [i*2 for i in range(10)] #格式一
l =[i*2 for i in range(10) if i>5] #格式二
  • 生成器函数

生成器函数:只需要把函数的return语句变成yield即可,yield将函数的返回值存入在生成器对象中,可以通过__next__()方法不断的取出下一个值,直到遇到StopIteration异常,终止调用。

举例

def test():
    for i in range(5):
        print("生成了",i*2)
        yield i*2
t = test()
print(type(t))
print(t.__next__())

好处:

延迟计算,可节约内存

  • 可迭代对象,迭代器对象,生成器三者关系图

猜你喜欢

转载自blog.csdn.net/Lzs1998/article/details/87900350