# iterator idea

Duncan Booth duncan.booth at invalid.invalid
Thu Oct 26 15:30:11 CEST 2006

```Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote:
...
> For example, the annoyance means itertools.takewhile consumes an extra
> element with no reasonable way to retrieve it.
...
>
>    def is_even(n): return (n%2 == 0)
>    def is_odd(n): return (n%2 != 0)
>
>    # we want to do something with all the runs of even numbers
>    # in the sequence, and similarly with the odds.  seq is an
>    # infinite sequence.
>    while True:
>        evens, seq = takewhile_exact(is_even, seq)
>        do_something_with (evens)
>        odds, seq = takewhile_exact(is_odd, seq)
>        do_something_else_with (odds)
>
> Without the "goto"-like transfer, we'd get deeper and deeper in nested
> iterators and eventually overflow the call stack.

I wouldn't agree that there is no way reasonable way to get the terminating
value with takewhile, you just need another generator or two:

>>> def repeatable(iterator):
it = iter(iterator)
for v in it:
while (yield v):
yield None

>>> def takeparts(predicates, iterator):
iterator = repeatable(iterator)
while True:
for pred in predicates:
yield takewhile(pred, iterator)
iterator.send(True)

>>> for seq in takeparts([is_even, is_odd], [2,2,4,5,6,6,7]):
print list(seq)

[2, 2, 4]
[5]
[6, 6]
[7]

```