Home > Enterprise >  Python - Use two zipped lists multiple times
Python - Use two zipped lists multiple times

Time:11-01

I have the following zip: a = zip(list_a, list_b). It was always my understanding that once I zipped a, it would stay zipped. Such that the following would work:

for iteration in range(100):
   for i, j in a:
      # do something

But I noticed that on the second iteration a was empty. First of all, is my understanding of zip correct, and secondly, is there a simple single line alternative that would fit in this situation?

CodePudding user response:

zip returns an iterator; it produces each pair once, then it's done. So the solution is usually to just inline the zip in the loop so it's recreated each time:

for iteration in range(100):
   for i, j in zip(list_a, list_b):
      # do something

or if that doesn't work for some reason, just list-ify the zip iterator up front so it's reusable:

a = list(zip(list_a, list_b))

and then use your original looping code.

CodePudding user response:

So, in the event that you actually just want to repeat your iterator n times, but not store anything intermediate:

import itertools


def repeat_iter(iterator, n):
    for it in itertools.tee(iterator, n):
        yield from it

This would be more useful if you need to pass your iterator around. The nested for loop in the accepted answer is probably sufficient for most use-cases.

Usage:

In [3]: a, b = [1, 2, 3], [4, 5, 6]

In [4]: g = repeat_iter(zip(a, b), 2)

In [5]: next(g)
Out[5]: (1, 4)

In [6]: next(g)
Out[6]: (2, 5)

In [7]: next(g)
Out[7]: (3, 6)

In [8]: next(g)
Out[8]: (1, 4)

In [9]: next(g)
Out[9]: (2, 5)

In [10]: next(g)
Out[10]: (3, 6)

In [14]: next(g)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-14-e734f8aca5ac> in <module>
----> 1 next(g)

If instead, you want to repeatedly iterate over zip(a, b) forever, you could also use itertools.cycle:

>>> c = itertools.cycle(zip(a, b))

>>> next(c)
(1, 4)

.
.
.
  • Related