On 2012-12-05 13:45, Chris Angelico wrote:
On Wed, Dec 5, 2012 at 12:17 PM, Nick Mellor <thebalance...@gmail.com> wrote:

takewhile mines for gold at the start of a sequence, dropwhile drops the dross 
at the start of a sequence.

When you're using both over the same sequence and with the same
condition, it seems odd that you need to iterate over it twice.
Perhaps a partitioning iterator would be cleaner - something like
this:

def partitionwhile(predicate, iterable):
     iterable = iter(iterable)
     while True:
         val = next(iterable)
         if not predicate(val): break
         yield val
     raise StopIteration # Signal the end of Phase 1
     for val in iterable: yield val # or just "yield from iterable", I think

Only the cold hard boot of reality just stomped out the spark of an
idea. Once StopIteration has been raised, that's it, there's no
"resuming" the iterator. Is there a way around that? Is there a clean
way to say "Done for now, but next time you ask, there'll be more"?

Perhaps you could have some kind of partitioner object:

class Partitioner:
    _SENTINEL = object()

    def __init__(self, iterable):
        self._iterable = iter(iterable)
        self._unused_item = self._SENTINEL

    def takewhile(self, condition):
        if self._unused_item is not self._SENTINEL:
            if not condition(self._unused_item):
                raise StopIteration

            yield self._unused_item
            self._unused_item = self._SENTINEL

        for item in self._iterable:
            if not condition(item):
                self._unused_item = item
                break

            yield item

        raise StopIteration

    def remainder(self):
        if self._unused_item is not self._SENTINEL:
            yield self._unused_item
            self._unused_item = self._SENTINEL

        for item in self._iterable:
            yield item

        raise StopIteration

def is_all_caps(word):
    return word == word.upper()

part = Partitioner("CAPSICUM RED fresh from QLD".split())
product = " ".join(part.takewhile(is_all_caps))
description = " ".join(part.remainder())
print([product, description])

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to