more fun with iterators (mux, demux)

pataphor pataphor at gmail.com
Wed Apr 8 11:06:52 CEST 2009


On 07 Apr 2009 02:05:59 GMT
Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> wrote:

> The demuxer can't be an iterator, since it needs to run through the 
> entire collection.

Then your demuxer obviously cannot handle infinite sequences.
 
> def demux(it, n):
>     collectors = [[] for i in xrange(n)]
>     i = 0
>     for item in it:
>         collectors[i].append(item)
>         i = (i+1) % n
>     return tuple([iter(x) for x in collectors])

But this one can:

from collections import deque
from itertools import cycle, izip, count, islice

def mux(*iterables):
    for it in izip(*iterables):
        for item in it:
            yield item

def demux(seq,n):
    it = iter(seq)
    Q = [deque() for i in xrange(n)]
    CQ = cycle(Q)
    def gen(D):
        for x,C in izip(it,CQ):
            C.appendleft(x)
            while D:  
                yield D.pop()        
        while D:  
            yield D.pop()        
    return map(gen,Q)

def test():
    a = count(10)
    b = count(20)
    c = count (30)
    x = demux(mux(a,b,c),3)
    for e in x:
        print list(islice(e,0,10))

if __name__=='__main__':
    test()

P.



More information about the Python-list mailing list