使用range()函数时,是否可以调用结果?

时间:2013-10-24 19:45:32

标签: python python-3.x iterator

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

next(j)将是n,但是我再次需要某个next(j)而没有前进,这是否可能没有进一步的复杂化?

5 个答案:

答案 0 :(得分:2)

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

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了解一些不错的解决方案。

答案 1 :(得分:0)

一种方法是使用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),所以......

答案 2 :(得分:0)

或您可以使用生成器语句

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

答案 3 :(得分:0)

您可以使用zip

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

答案 4 :(得分:0)

我相信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