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