附代码 什么是Python的迭代器和生成器?( 三 )

我们可以创建Sequence对象来遍历Sequence类 , 在该对象上调用next()方法:
it = Sequence()  print(next(it))  print(next(it))  print(next(it))  print(next(it))  print(next(it)) 

附代码 什么是Python的迭代器和生成器?

文章插图
 
我没有写sequence结束的条件 , 因此迭代器将永远继续返回下一个值 。但我们可以使用停止条件轻松地对其进行更新:
sample = ['statistics', 'linear algebra', 'probability']    # iterator  it = iter(sample)    # next values  print(next(it))  print(next(it))  print(next(it))我刚刚加入了一条if语句 , 只要值超过10 , 该语句就会停止迭代:
it = Sequence()  for i in it:       print(i)
附代码 什么是Python的迭代器和生成器?

文章插图
 
在这里 , 我没有使用next()方法从迭代器返回值 , 而是使用了for循环 , 该循环的工作方式与之前相同 。
熟悉Python中的生成器生成器也是迭代器 , 但更加优雅 。使用生成器 , 我们可以实现与迭代器相同的功能 , 但不必在类中编写iter()和next()函数 。相反 , 我们可以使用一个简单的函数来完成与迭代器相同的任务:
# fibonacci sequence using a generator   def fib():         prev, curr = 0, 1      # infinite loop      while prev<5:          value = prev          # Calculate the next number in the sequence. Using Tuple unpacking.          prev, curr = curr, prev + curr          # yield the value          yield value  你是否注意到这个生成器函数和常规函数的不同?是的 , yield关键字!
普通函数使用return关键字返回值 。但是生成器函数使用yield关键字返回值 。这就是生成器函数与常规函数不同的地方(除了这种区别 , 它们是完全相同的) 。
yield关键字的工作方式类似于普通的return关键字 , 但有额外的功能:它能记住函数的状态 。因此 , 下次调用generator函数时 , 它不是从头开始 , 而是从上次调用中停止的位置开始 。
让我们看看它是如何工作的:
# generator object  gen=fib()  print(gen)  # values  print(next(gen))  print(next(gen))  print(next(gen))  print(next(gen))  print(next(gen))  
附代码 什么是Python的迭代器和生成器?

文章插图
 
生成器属于“生成器”类型 , 它是迭代器的一种特殊类型 , 但仍然是迭代器 , 因此它们也是懒惰的工作者 。除非next()方法明确要求它们这样做 , 否则它们不会返回任何值 。
最初创建fib()生成器函数的对象时 , 它会初始化prev和curr变量 。现在 , 当在对象上调用next()方法时 , 生成器函数会计算值并返回输出 , 同时记住函数的状态 。因此 , 下次调用next()方法时 , 该函数将从上次停止的地方开始 , 从那里继续 。
每当使用next()方法时 , 该函数将继续生成值 , 直到prev变得大于5 , 这时将引起StopIteration异常 , 如下所示:
print(next(gen))
附代码 什么是Python的迭代器和生成器?

文章插图
 
实现Python中的生成器表达式你不必在每次执行生成器时都编写函数 。相反 , 你可以使用生成器表达式 , 就像列表生成式一样 。唯一的区别是 , 与列表生成式不同 , 生成器表达式包含在圆括号内 , 如下所示:


推荐阅读