Enhanced Generators - the difference between sources and iterators

Kragen Sitaker kragen at pobox.com
Fri Feb 1 19:51:01 EST 2002


Oren Tirosh <oren-py-l at hishome.net> writes:
> My implementation of xmap, xfilter and xzip returns a source, not an
> iterator.  It can be iterated multiple times, just like the output of map,
> filter or zip.

That won't work when passed iterators as arguments, right?

> The logical opposite of a source is a destination.  Destinations should
> be able to produce a temporary object mirroring an iterator.  I call such 
> an object a sink (PLUG: see http://tothink.com/python/dataflow)

Well, if you want to have two pieces of code with independent local
control state connected by a stream of values, in which the sink runs
until it needs a new value, and then the source runs until it produces
a new value, after which the sink runs again etc., generators give you
that already.  Having "sinks" just gives you another way to do the
same thing.  Are there some situations where structuring a piece of
code with some hypothetical "accept" expression would yield (pardon
the pun!) something simpler than just doing the same thing with
generators?

Suppose you have this program:

def uniq(iterable):
    state = {}
    for x in iterable:
        if not state.has_key('prev') or x != state['prev']:
            print x
        state['prev'] = x

Now, if we have this hypothetical "accept" operation that is the other
side of 'yield', we can make this into a lazy sink:

def uniq():
    state = {}
    while 1:
        x = accept
        if not state.has_key('prev') or x != state['prev']:
            print x
        state['prev'] = x

That's not any simpler.  The code that represents uniq's source also
doesn't get simpler.  It changes from this:

def uniqsource():
    mystate = initializemystate()
    while mystate.continuing():
        mystate.update()
        yield mystate.nextvalue()

to this:

def uniqsource(outputthing):
    mystate = initializemystate()
    while mystate.continuing():
        mystate.update()
        outputthing.feed(mystate.nextvalue())

That's also not any simpler.  Are there examples where the second pair
is noticeably simpler than the first?  I doubt it.




More information about the Python-list mailing list