当前位置: 首页 > 面试题库 >

如何防止迭代器用尽?

段干靖
2023-03-14
问题内容

如果我创建两个列表并将其压缩

a=[1,2,3]
b=[7,8,9]
z=zip(a,b)

然后我将z输入到两个列表中

l1=list(z)
l2=list(z)

那么,l1的内容就很好了[(1,7),(2,8),(3,9)],但是l2的内容只是[]。

我猜想这是python关于可迭代项的一般行为。但是,作为从C家族迁移的新手程序员,这对我来说没有意义。为什么会这样表现?有办法解决这个问题吗?

我的意思是,是的,在这个特定示例中,我可以将l1复制到l2中,但是总的来说,在迭代一次之后,是否有一种方法可以“重置” Python用于迭代“ z”的内容?


问题答案:

无法“重置”生成器。但是,您 可以 使用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 ** 2

def 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确实是实现协程的,所以我不会将其用于此目的。每天生成器几乎永远不会对发送给它们的值做任何事情-
我认为出于上述原因。



 类似资料:
  • 我用alpha-beta修剪创建了一个极大极小函数,我用迭代深化调用它。问题是,当计时器完成时,该函数会一直运行,直到在计时器用完之前,它在开始的深度上完成为止。 我想要的是:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回之前计算的best move。我似乎不知道如何在minimax函数中实

  • 我用的是JavaFX。 当某个文件没有加载时,我希望阶段关闭,该实例中的代码停止执行。

  • 本文向大家介绍如何防止cookie被盗用?相关面试题,主要包含被问及如何防止cookie被盗用?时的应答技巧和注意事项,需要的朋友参考一下 禁止第三方网站带cookie(same-site属性) 每次请求需要输入图形验证码 使用Token验证 为cookie设置HttpOnly 设置CSP 使用Referer验证 禁止网页内嵌 使用https cookie带上用户ip加密

  • 我尝试使用布尔值来仅显示是否找到我使用的代码: 然后在两个打印语句中,我输入: 并在底部放置: 并且仍然在为每个循环的每一次迭代获取输出。我试图做的是在中的每一次获得一个输出,该数字出现在已排序和未排序的中,然后是数组列表中所有数字的总和。 编辑1:我得到的当前输出是,它表示有多少个数字,因此它输出的是 time的数量,其中 是numOfNumbers。我希望它只输出它在两个数组中出现的次数。编辑

  • 我想在HashMap中搜索重复项。目前这是我的HashMap:

  • 迭代器 乍看来,迭代器似乎很直观。但凑近了看,你会发现标准STL容器提供了四种不同的迭代器:iterator、const_iterator、reverse_iterator和const_reverse_iterator。很快你会注意到在这四种类型中,容器的insert和erase的某些形式只接受其中一种。那是问题的开始。为什么有四种迭代器?它们之间的关系是什么?它们可以互相转化吗?在调用算法和ST