Title: splice() function for itertools
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 2.6
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: asdutton, rhettinger
Priority: normal Keywords:

Created on 2007-07-20 09:12 by asdutton, last changed 2007-07-22 16:51 by rhettinger. This issue is now closed.

Messages (3)
msg55148 - (view) Author: Alexander Dutton (asdutton) Date: 2007-07-20 09:12
Could we have a splice function in itertools? I see there was once a roundrobin proposal (#756253), but it was three years ago ...

Here's an alternate implementation:

def splice(*args):
  """splice(*iterables) --> iterator
  Returns an iterator whose next() method returns an element from each of the iterables in turn before starting again with the first iterable."""
  iters = list(args)
  n = len(iters)
  i = 0
  while n>0:
    i %= n
      yield iters[i].next()
      i += 1
    except StopIteration, e:
      n -= 1
      iters[i:i+1] = []
  raise StopIteration
msg55149 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2007-07-22 16:19
The reasons for rejecting the roundrobin proposal still apply three years later.  It is somewhat use case challenged.

FWIW, there is a reasonably efficient pure python implementation using collections.deque().  See for an unoptimized recipe which can be fine-tuned to use bound methods and all local variables for better speed.
msg55150 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2007-07-22 16:51
FWIW, here is the optimized recipe:

def roundrobin(*iterables):
    pending = deque(iter(i).next for i in reversed(iterables))
    rotate, pop, _StopIteration = pending.rotate, pending.pop, StopIteration
    while pending:
            while 1:
                yield pending[-1]()
        except _StopIteration:
Date User Action Args
2007-07-20 09:12:21asduttoncreate