From 0858495a50e19defde786a4ec050ec182e920f46 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 23 Nov 2017 13:32:23 -0800 Subject: bpo-32099 Add deque variant of roundrobin() recipe (#4497) * Minor wording tweaks --- Doc/library/collections.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index cda8296..4b0d8c0 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -618,6 +618,25 @@ added elements by appending to the right and popping to the left:: d.append(elem) yield s / n +A `round-robin scheduler +`_ can be implemented with +input iterators stored in a :class:`deque`. Values are yielded from the active +iterator in position zero. If that iterator is exhausted, it can be removed +with :meth:`~deque.popleft`; otherwise, it can be cycled back to the end with +the :meth:`~deque.rotate` method:: + + def roundrobin(*iterables): + "roundrobin('ABC', 'D', 'EF') --> A D E B F C" + iterators = deque(map(iter, iterables)) + while iterators: + try: + while True: + yield next(iterators[0]) + iterators.rotate(-1) + except StopIteration: + # Remove an exhausted iterator. + iterators.popleft() + The :meth:`rotate` method provides a way to implement :class:`deque` slicing and deletion. For example, a pure Python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: -- cgit v0.12