On Oct 25, 4:33 am, Kelson Zawack <[email protected]> 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