Has Next in Python Iterators

K

Kelson Zawack

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. Since an
iterator having an end is not actually an exceptional case and the for
construct is really for iterating though the entirety of a list both of
these solutions feel like greasy workarounds and thus not very
pythonic. Is there something I am missing? Is there a reason python
iterators don't have has_next functionality? What is the standard
solution to this problem?
 
S

Steven D'Aprano

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.
 
P

Paul Rudin

Kelson Zawack said:
Since an iterator having an end is not actually an exceptional case...

There's no requirement on iterators to be finite, so in a sense it is.

In general it may be impractical to know whether an iterator has reached
the end without calling next().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top