multirember&co

Anton Vredegoor anton.vredegoor at gmail.com
Thu Apr 19 11:38:01 EDT 2007


Anton Vredegoor wrote:
> attn.steven.kuo at gmail.com wrote:
> 
>> Try it with
>>
>> def test():
>>     L = 'a', 1, 2, 'a'
>>     it1, it2 = xsplitter(L, lambda x: x == 'a')
>>     print it1.next()
>>     print it2.next()
>>     print it1.next()
>>     print it2.next()
>>
>>
>> The last print statement raises StopIteration...
>> We, however, expected each iterator to contain
>> two elements (one yielding 'a' then 'a', and
>> the other yielding 1 then 2).
> 
> Ouch! I never understood much about generators anyway.

How about this one?

from collections import deque

class sentinel(object):
     pass

class myiter(object):

     def __init__(self,seq):
         self.seq = seq
         self.index = -1

     def __iter__(self):
         return self

     def next(self):
         self.index +=1
         if self.index < len(self.seq):
             return self.seq[self.index]
         else:
             return sentinel

def mygen(seq):
     for x in seq:
         if x is sentinel: #way past bedtime
             raise StopIteration
         yield x

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

def test():
     L = 'a', 1, 2, 'a'
     it1, it2 = xsplitter(L, lambda x: x == 'a')
     print it1.next()
     print it2.next()
     print it1.next()
     print it2.next()

if __name__=='__main__':
     test()

A.



More information about the Python-list mailing list