On Apr 16, 5:14 pm, [EMAIL PROTECTED] wrote: > Once in while I too have something to ask. This is a little problem > that comes from a Scheme Book (I have left this thread because this > post contains too much Python code for a Scheme > newsgroup):http://groups.google.com/group/comp.lang.scheme/browse_thread/thread/... >
(snipped) > > For fun I have tried to make it lazy, if may be useful if seq is a > very long iterable. So I've used tee: > > from itertools import ifilter, tee > > def multiremberandco4(el, iseq, fun): > iseq1, iseq2 = tee(iseq) > iterable1 = ifilter(lambda x: x == el, iseq1) > iterable2 = ifilter(lambda x: x != el, iseq2) > return fun(iterable1, iterable2) > > def leniter(seq): > count = 0 > for el in seq: > count += 1 > return count > > idata = iter(data) > print multiremberandco4('a', idata, lambda l1,l2: (leniter(l1), > leniter(l2))) > > But from the docs: >in general, if one iterator is going to use most > or all of the data before the other iterator, it is faster to use > list() instead of tee().< > > So I have tried to create two iterables for the fun function scanning > seq once only, but I haven't succed so far (to do it I have tried to > use two coroutines with the enhanced generators, sending el to one or > to the other according to the value of x == el, this time I don't show > my failed versions), do you have suggestions? Scan once, two iterables: class It(object): def __init__(self, iseq, fun, fun2): self.iseq = iseq self.wanted = fun self.queue = [] self.divert = fun2 def append(self, item): self.queue.append(item) def __iter__(self): while True: if self.queue: yield self.queue.pop(0) else: try: item = self.iseq.next() if self.wanted(item): yield item else: self.divert(item) except StopIteration: raise class TwoFromOne(object): def __init__(self, iseq, el): self.i1 = It(iseq, lambda x: x == el, lambda y: self.i2.append(y)) self.i2 = It(iseq, lambda x: x != e1, lambda y: self.i1.append(y)) def getiters(self): return self.i1, self.i2 def leniter(seq): count = 0 for el in seq: count += 1 return count data = [1, 'a', 3, 'a', 4, 5, 6, 'a'] lazy_eye = TwoFromOne(iter(data), 'a') it1, it2 = lazy_eye.getiters() print (lambda i1, i2: (leniter(i1), leniter(i2)))(it1, it2) -- Hope this helps, Steven -- http://mail.python.org/mailman/listinfo/python-list