【问题标题】:While using the range() function, is it possible to recall a result?使用 range() 函数时,是否可以调用结果?
【发布时间】:2013-11-03 16:57:06
【问题描述】:

我正在使用iter(range()),但我还需要使用两次结果,假设j=iter(range(n,2n))

next(j) 将是 n,但我需要再次确定 next(j) 而不向前走,这可能没有进一步的复杂性吗?

【问题讨论】:

    标签: python python-3.x iterator


    【解决方案1】:

    您可以轻松编写一个生成器,将给定迭代器的每个元素重复两次:

    def repeat_iter(iter, n = 2):
        for x in iter:
            for i in range(n):
                yield x
    
    for x in repeat_iter(range(n)):
        print x
    

    如果您的用例需要向前看,请参阅this question 了解一些不错的解决方案。

    【讨论】:

      【解决方案2】:

      一种方法是显式获取两个迭代器,使用itertools.tee

      iter1,iter2 = itertools.tee(iter(range(5,10)))
      
      next(iter1)
      Out[15]: 5
      
      next(iter2)
      Out[16]: 5
      

      这可能更灵活,具体取决于您在做什么,但缺点是您需要确保从两个迭代器中进行一对一的消费。

      但老实说,我认为我从未发现自己使用range 这样做过。当您将next() 分配给一个变量时,您可以根据需要多次访问它(a la for i in range),所以...

      【讨论】:

        【解决方案3】:

        或者你可以使用生成器语句

        for i in (j for j in range(n, 2 * n) for k in range(2)):
            pass
        

        【讨论】:

          【解决方案4】:

          你可以使用zip:

          for a, b in zip(range(...), range(...)):
              ...
          

          【讨论】:

            【解决方案5】:

            我相信shx2's answer 是问题的正确答案。

            但是,如果

            • 你只需要重用其中的一些值,在迭代器创建的时候并不知道你需要重新出现哪些值,或者
            • 某些值可能需要比其他值更频繁地重复,

            那么这里有一个不同的生成器,它可以通过 send() builtin 对反馈做出反应。

            def iter_with_standstill(iter):
                standstill = False
                for x in iter:
                    while True:
                        pause = yield x
                        if pause is not None:
                            standstill = pause
                            yield None
                        if not standstill:
                            break
            

            使用的技巧是任何generator.send(value) 的调用都会将value 作为yield 的结果接收它的生成器发送回。由于任何send() 都会导致生成器也立即运行到下一个yield(),我们yield(None) 在这里立即将控制权交还给调用代码。这种方法使send()真正实现了单向操作。

            使用方法如下:

            orig = range(10)
            paused = iter_with_standstill(orig)
            
            waiting = None
            for x in paused:
                if x in [4,7]:
                    if waiting is None:
                        waiting = 3
                    waiting -= 1
                    if waiting > 0:
                        paused.send(True)
                    else:
                        paused.send(False)
                        waiting = None
                print(x, end=' ')
            print()
            

            waiting 变量的全部意义在于在值 4 和 7 处暂停,并重新迭代这些值最多 3 次。输出如下:

            0 1 2 3 4 4 4 5 6 7 7 7 8 9 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-03-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-12
              • 2023-03-04
              • 1970-01-01
              相关资源
              最近更新 更多