Skip to content Skip to sidebar Skip to footer

Re-using Zip Iterator In Python 3

I have the zip object: L_RANGES = zip(range(10, 20), range(11, 21)) First call of L_RANGES is ok: print(type(L_RANGES)) for a, b in L_RANGES: print(a, b) Output:

Solution 1:

If you were to create a generator each time you loop, that would solve everything, because you could reuse that multiple times. For that, convert L_RANGES from a simple generator to a lambda creating generators, but don't forget to "call" it each time with ():

L_RANGES = lambda: zip(range(10, 20), range(11, 21))

for a, b in L_RANGES():
  print(a, b)

for a, b in L_RANGES():
  print(a, b)

#works as many times as you want

Compared to the other answers this doesn't take up memory (which is the downside of converting to a list) and doesn't require multiple variables for each time you want to loop (by using tee) which makes this way more flexible (you can iterate 1000 times if necessary, without creating L_RANGES_1...L_RANGES_999) for example:

for i in range(1000):
    for a, b in L_RANGES():
        print(a, b)

Solution 2:

An iterator, once exhausted, may not be reused. In Python 3.x, zip returns an iterator. One solution is to use itertools.tee to copy an iterator n times.

For example, setting n = 2, we can do the following:

from itertools import tee

L_RANGES_1, L_RANGES_2 = tee(zip(range(10, 20), range(11, 21)), 2)

for item in L_RANGES_1:
    # do somethingfor item in L_RANGES_2:
    # do something else

Conversion to a list allows use an arbitrary number of times, but is inadvisable for large iterables due to the memory overhead.

For a large number of copies, you can use a dictionary. For example:

L_RANGES = dict(zip(range(1000), tee(zip(range(10, 20), range(11, 21)), 1000)))

Solution 3:

In Python 3.x zip() returns iterator that gets exhausted.

Simplest way to avoid it is:

L_RANGES = list(zip(range(10, 20), range(11, 21)))

Post a Comment for "Re-using Zip Iterator In Python 3"