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