On Oct 25, 4:33 am, Kelson Zawack <zawack...@gis.a-star.edu.sg> wrote:
> The example I have in mind is list like [2,2,2,2,2,2,1,3,3,3,3] where
> you want to loop until you see not a 2 and then you want to loop until
> you see not a 3.  In this situation you cannot use a for loop as
> follows:
>
> foo_list_iter = iter([2,2,2,2,2,2,1,3,3,3,3])
> for foo_item in foo_list_iter:
>     if foo_item != 2:
>         break
> because it will eat the 1 and not allow the second loop to find it.
> takeWhile and dropWhile have the same problem.  It is possible to use
> a while loop as follows:
>
> foo_list_item = foo_list_iter.next()
> while foo_list_item == 2:
>     foo_list_item = foo_list_iter.next()
> while foo_list_item == 3:
>     foo_list_item = foo_list_iter.next()
>
> but if you can't be sure the list is not empty/all 2s then all 3s you
> need to surround this code in a try block.  Unless there is a good
> reason for having to do this I think it is undesirable because it
> means that the second clause of the loop invariant, namely that you
> are not off the end of the list, is being controlled outside of the
> loop.

from itertools import chain, imap, izip, tee
from operator import itemgetter

foo_list_iter, next_foo_list_iter = tee([2,2,2,2,2,2,1,3,3,3,3])
next_foo_list_iter = chain([None], next_foo_list_iter)
foo_list_iter = imap(itemgetter(0), izip(foo_list_iter,
next_foo_list_iter))

for foo_item in foo_list_iter:
    if foo_item != 2:
        foo_list_iter = next_foo_list_iter
        break

But in practice I think the best solution is to create an explicit
iterator wrapper that implements hasnext() and use it as needed, as
others in this thread have suggested.

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to