Python problem 30 of 30

Round robin

  • Python
  • Hard

Write roundrobin(*iterables) that takes one item from each input in turn, skipping inputs that have run out, until all of them are used up. It should work for any iterables, not just lists.

roundrobin("ABC", "D", "EF")
# ["A", "D", "E", "B", "F", "C"]
Show hint

Turn each input into an iterator with iter(), then call next() on each in turn. next raises StopIteration when an iterator is finished.

Show solution
def roundrobin(*iterables):
    iterators = [iter(it) for it in iterables]
    out = []
    while iterators:
        still_going = []
        for it in iterators:
            try:
                out.append(next(it))
            except StopIteration:
                continue
            still_going.append(it)
        iterators = still_going
    return out

Each round asks every live iterator for one item and keeps only those that produced something. Using iterators instead of indexes means it works for files, generators and anything else you can loop over. This is how a simple scheduler shares time between tasks.

Want a problem like this every day? See today's problem and keep a streak going.