I'm using iter(range())
, but I also need to use the results twice, assuming j=iter(range(n,2n)
)
next(j)
would be n, but then I need that certain next(j)
again without stepping forward, Is that possible without further complications?
I'm using iter(range())
, but I also need to use the results twice, assuming j=iter(range(n,2n)
)
next(j)
would be n, but then I need that certain next(j)
again without stepping forward, Is that possible without further complications?
You can easily write a generator which repeats each element of a given iterator twice:
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
If what your use case requires is looking ahead, see this question for some nice solutions.
One approach is to explicitly get two iterators, using itertools.tee
:
iter1,iter2 = itertools.tee(iter(range(5,10)))
next(iter1)
Out[15]: 5
next(iter2)
Out[16]: 5
This can be more flexible depending on what you're doing, but the downside is that you need to make sure you're going 1-for-1 consuming from both iterators.
But honestly I don't think I've ever found myself doing this with range
. When you assign next()
to a variable, you can access it as many times as you want (a la for i in range
), so...
or You can use generator statement
for i in (j for j in range(n, 2 * n) for k in range(2)):
pass
I believe shx2's answer to be the correct answer to the question.
However, in the case where
then here's a different generator that can react on feedback via the 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
The trick used is that any call of generator.send(value)
will send back the value
to the generator which receives it as the result of yield
. As any send()
will cause the generator to also immediately run up to the next yield()
, we yield(None)
here to give back control immediately to the calling code. This method makes send()
to truly operate as a one way operation.
Here's how to use it:
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()
The whole point of the waiting
variable is to pause at the values 4 and 7, and re-iterating those values up to a total of 3 times. The output looks like:
0 1 2 3 4 4 4 5 6 7 7 7 8 9