multirember&co

Anton Vredegoor anton.vredegoor at gmail.com
Wed Apr 18 15:23:10 EDT 2007


attn.steven.kuo at gmail.com wrote:
> 
> If you don't wish to use objects, you can replace them with
> a closure:
> 
> import collections
> 
> def xsplitter(iseq, pred):
>     queue = [ collections.deque(), collections.deque() ]
>     def it(parity):
>         while True:
>             if queue[parity]:
>                 yield queue[parity].popleft()
>             else:
>                 try:
>                     el = iseq.next()
>                     if pred(el) == parity:
>                         yield el
>                     else:
>                         queue[not parity].append(el)
>                 except StopIteration:
>                     raise
>     its = [ it(False), it(True) ]
>     return its[True], its[False]
> 
> 
> idata = iter([1, 'a', 3, 'a', 4, 5, 6, 'a'])
> it1, it2 = xsplitter(idata, lambda x: x == 'a')
> 
> from itertools import izip
> for el1, el2 in izip(it1, it2):
>     print el1, el2
> 
> 
> Oh, I and do like your rewrite; it's much less
> repetitive and cleaner than my original version.

But still, the 'while True:' loop and the 'try-except' clause and the 
explicit StopIteration are not necessary ...

from collections import deque

def xsplitter(seq, pred):
     Q = deque(),deque()
     it = iter(seq)
     def gen(p):
         while Q[p]:  yield Q[p].popleft()
         for x in it:
             if pred(x) == p: yield x
             else:
                 Q[~p].append(x)
                 for x in gen(p):  yield x
     return gen(1),gen(0)

def test():
     L = 1, 'a', 3, 'a', 4, 5, 6, 'a'
     it1, it2 = xsplitter(L, lambda x: x == 'a')
     print it1.next()
     print it2.next()
     print it1.next()

if __name__=='__main__':
     test()

A.



More information about the Python-list mailing list