我们可以创建Sequence对象来遍历Sequence类 , 在该对象上调用next()方法:
it = Sequence() print(next(it)) print(next(it)) print(next(it)) print(next(it)) print(next(it))
文章插图
我没有写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)
文章插图
在这里 , 我没有使用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))
文章插图
生成器属于“生成器”类型 , 它是迭代器的一种特殊类型 , 但仍然是迭代器 , 因此它们也是懒惰的工作者 。除非next()方法明确要求它们这样做 , 否则它们不会返回任何值 。
最初创建fib()生成器函数的对象时 , 它会初始化prev和curr变量 。现在 , 当在对象上调用next()方法时 , 生成器函数会计算值并返回输出 , 同时记住函数的状态 。因此 , 下次调用next()方法时 , 该函数将从上次停止的地方开始 , 从那里继续 。
每当使用next()方法时 , 该函数将继续生成值 , 直到prev变得大于5 , 这时将引起StopIteration异常 , 如下所示:
print(next(gen))
文章插图
实现Python中的生成器表达式你不必在每次执行生成器时都编写函数 。相反 , 你可以使用生成器表达式 , 就像列表生成式一样 。唯一的区别是 , 与列表生成式不同 , 生成器表达式包含在圆括号内 , 如下所示:
推荐阅读
- 单株古树茶是什么,8种普洱古树纯料茶
- 2021双十一活动什么时候开始?
- 三大平原中面积最大的是什么?
- 世界十大最昂贵名画是什么?
- 纯元皇后为什么叫菀菀?
- 什么星座最疼摩羯座?
- 《大王饶命》的吕小鱼结局是什么?
- 淘宝上架用什么软件 淘宝自动上下架最好的软件
- 道家养生与中医养生,养生是什么
- 春季爬山的好处 要注意些什么