Here is an elegant solution:
def alternate(*iterators): while len(iterators) > 0: try: yield next(iterators[0])
Using the actual queue to improve performance (as David suggested):
from collections import deque def alternate(*iterators): queue = deque(iterators) while len(queue) > 0: iterator = queue.popleft() try: yield next(iterator) queue.append(iterator) except StopIteration: pass
It works even if some iterators are finite and others are infinite:
from itertools import count for n in alternate(count(), iter(range(3)), count(100)): input(n)
Print
0 0 100 1 1 101 2 2 102 3 103 4 104 5 105 6 106
It also stops correctly if / when all iterators have been exhausted.
If you want to process iterators without an iterator, like lists, you can use
def alternate(*iterables): queue = deque(map(iter, iterables)) ...
user76284 Nov 09 '16 at 0:10 2016-11-09 00:10
source share