[Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation
Serhiy Storchaka
storchaka at gmail.com
Tue Nov 21 05:44:38 EST 2017
21.11.17 11:44, Serhiy Storchaka пише:
> The roundrobin() implementation in recipes has quadratic time for large
> number of iterables. As well as all other proposed implementations. This
> is a problem if you use it with hundreds or thousands of iterables. For
> example:
>
> list(roundrobin(*([[1]]*1000)))
> next(roundrobin(*([[]]*1000 + [[1]]])))
>
> The following implementation has linear time.
>
> def roundrobin(*iterables):
> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> nexts = [iter(it).__next__ for it in iterables]
> while nexts:
> next_nexts = []
> append = next_nexts.append
> for next in nexts:
> try:
> yield next()
> except StopIteration:
> pass
> else:
> append(next)
> nexts = next_nexts
>
> Actually it expands cycle() in Python. And this makes it slower for
> smaller number of iterations.
Yet one natural implementation with linear time is:
from collections import deque
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
nexts = deque(iter(it).__next__ for it in iterables)
popleft = nexts.popleft
append = nexts.append
while nexts:
next = popleft()
try:
yield next()
except StopIteration:
pass
else:
append(next)
As the previous example it doesn't have any relation to itertools.
More information about the Python-ideas
mailing list