Write a generator that takes in any number of iterables and zips them together. It should output a series of lists, each containing the nth items of each iterable. It should stop when the smallest iterable runs out of elements. For example:

``````def zip(     ):
"""
>>> z = zip([1, 2, 3], [4, 5, 6], [7, 8])
>>> for i in z:
...     print(i)
...
[1, 4, 7]
[2, 5, 8]
"""
``````

Toggle Solution

``````def zip(*iterables):
"""
>>> z = zip([1, 2, 3], [4, 5, 6], [7, 8])
>>> for i in z:
...     print(i)
...
[1, 4, 7]
[2, 5, 8]
"""
iterators = [iter(iterable) for iterable in iterables]
while True:
yield [next(iterator) for iterator in iterators]
``````

There were several concepts that were tested in this problem. The first was the * syntax most commonly associated with `*args`. Remember that `args` is just the name of the list of arguments, but the variable can be named anything. For this problem, we’re going to call it `iterables` because it’s going to be a list of iterables. Since they are iterables, we need to make them all into iterators so the best way to do this is call `iter` on each of the iterables to make iterators. This can also be done using `map`. Next, we need a loop that runs to the end of the shortest iterator, however, we note that when we reach the end of the shortest iterator, we need to raise a `StopIteration`. We then note that when calling `next` on an iterator that is out of elements, it raises a `StopIteration`! So, our job is mainly complete and we can just yield the next items of each iterator. When one iterator runs out of elements, it will raise a `StopIteration` which in turn will make the `zip` function return a `StopIteration` as well.

I don't claim to be perfect so if you find an error on this page, please send me an email preferably with a link to this page so that I know what I need to fix!