栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何防止迭代器用尽?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何防止迭代器用尽?

无法“重置”生成器。但是,您 可以 使用

itertools.tee
“复制”迭代器。

>>> z = zip(a, b)>>> zip1, zip2 = itertools.tee(z)>>> list(zip1)[(1, 7), (2, 8), (3, 9)]>>> list(zip2)[(1, 7), (2, 8), (3, 9)]

这涉及到缓存值,因此仅当您以大约相同的速率遍历两个可迭代对象时才有意义。(换句话说,不要像我在这里那样使用它!)

另一种方法是传递生成器函数,并在需要迭代时调用它。

def gen(x):    for i in range(x):        yield i ** 2def make_two_lists(gen):    return list(gen()), list(gen())

但是现在,您必须在传递函数时将参数绑定到生成器函数。您可以使用

lambda
它,但是很多人都觉得
lambda
丑陋。(虽然不是我!YMMV。)

>>> make_two_lists(lambda: gen(10))([0, 1, 4, 9, 16, 25, 36, 49, 64, 81], [0, 1, 4, 9, 16, 25, 36, 49, 64, 81])

我希望不用多说,在大多数情况下,最好列出并复制列表。

另外,作为解释此行为的更一般方法,请考虑一下。生成器的作用是生成一系列值,同时在迭代之间保持某种状态。现在,有时,您可能不希望简单地在生成器上进行迭代,而是要执行以下操作:

z = zip(a, b)while some_condition():    fst = next(z, None)    snd = next(z, None)    do_some_things(fst, snd)    if fst is None and snd is None:        do_some_other_things()

假设此循环 可能会可能不会
耗尽

z
。现在,我们的发电机处于不确定状态!因此,在这一点上,必须以明确定义的方式限制生成器的行为。尽管我们不知道生成器在其输出中的位置,但我们知道a)所有后续访问都会在该系列中产生
更高的
值,并且b)一旦它为“空”,我们就可以准确地获得该系列中的所有项目一旦。我们必须具有越多的能力来操纵的状态,就越
z
难以对此进行推理,因此最好避免出现违反这两个诺言的情况。


当然,正如乔尔·科内特(Joel Cornett)在下面指出的那样,
可能编写一个通过该

send
方法接受消息的生成器。并且可以编写可以使用重置的生成器
send
。但是请注意,在这种情况下,
我们所能做的就是发送一条消息 。我们不能直接操纵生成器的状态,因此对生成器状态的所有更改都是定义明确的(通过生成器本身-
假设其编写正确!)。
send
确实是实现协程的,所以我不会将其用于此目的。每天生成器几乎永远不会对发送给它们的值做任何事情-
我认为出于上述原因。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/610655.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号