Has Next in Python Iterators

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Oct 21 08:39:25 EDT 2010


On Thu, 21 Oct 2010 19:08:00 +0800, Kelson Zawack wrote:

> I have been programing in python for a while now and by in large love
> it.  One thing I don't love though is that as far as I know iterators
> have no has_next type functionality.  As a result if I want to iterate
> until an element that might or might not be present is found I either
> wrap the while loop in a try block or break out of a for loop.

Yes, they are two solutions to the problem. You could also look at 
takewhile and dropWhile from the itertools module.


> Since an
> iterator having an end is not actually an exceptional case 

But it is. An iterator is supposed to yield items. That's what they're 
for. When there are no more items, that's an exceptional change of state.

> and the for
> construct is really for iterating though the entirety of a list

Nonsense. That's why Python has continue and break statements, so you can 
break out of for loops early. But if you don't like break, you could 
always use a while loop.


> both of
> these solutions feel like greasy workarounds and thus not very pythonic.

I can't help how they feel to you, but I assure you they are perfectly 
Pythonic.


>  Is there something I am missing?  Is there a reason python iterators
> don't have has_next functionality?  

Yes. What you ask for is impossible to implement for generic iterators. 
Not hard. Not inconvenient. Impossible.

Of course you can implement it yourself in your own iterators:


class LookAheadIterator:
    def __init__(self, n):
        self.n = n
    def next(self):
        if self._n < 0:  raise StopIteration
        self._n -= 1
        return self._n + 1
    def __iter__(self):
        return self
    def hasNext(self):
        return self._n >= 0


but there's no general solution that will work for arbitrary iterators.


-- 
Steven



More information about the Python-list mailing list