Welcome, guest | Sign In | My Account | Store | Cart

This recipe implements a round-robin generator, a generator that cycles through N iterables until all of them are exhausted:

>>> list(roundrobin('abc', [], range(4),  (True,False)))
['a', 0, True, 'b', 1, False, 'c', 2, 3]
Python, 11 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from itertools import cycle, islice

def roundrobin(*iterables):
    pending = len(iterables)
    nexts = cycle(iter(iterable).next for iterable in iterables)
    while pending:
        try:
            for next in nexts: yield next()
        except StopIteration:
            pending -= 1
            nexts = cycle(islice(nexts, pending))

Round-robin is one of the simplest scheduling algorithms, where the scheduler assigns resources (e.g. processes) to each consumer in equal portions and in order. There is already a roundrobin recipe (http://docs.python.org/lib/deque-recipes.html) that uses a deque for popping iterables from the one end and pushing them to the other as long as they are not exhausted. This recipe uses itertools.cycle instead and is more efficient for long streams as it avoids all the pushing and popping.