Python迭代器有has_next方法吗?


当前回答

hasNext在某种程度上转换为StopIteration异常,例如:

>>> it = iter("hello")
>>> it.next()
'h'
>>> it.next()
'e'
>>> it.next()
'l'
>>> it.next()
'l'
>>> it.next()
'o'
>>> it.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

StopIteration文档:http://docs.python.org/library/exceptions.html#exceptions.StopIteration 一些关于python中的迭代器和生成器的文章:http://www.ibm.com/developerworks/library/l-pycon.html

其他回答

我认为当你想要某种has_next功能时,有一些有效的用例,在这种情况下,你应该用定义了has_next的迭代器来装饰迭代器。

结合这个问题的答案的概念,这里是我的实现,这对我来说是一个很好的简洁的解决方案(python 3.9):

_EMPTY_BUF = object()


class BufferedIterator(Iterator[_T]):
    def __init__(self, real_it: Iterator[_T]):
        self._real_it = real_it
        self._buf = next(self._real_it, _EMPTY_BUF)

    def has_next(self):
        return self._buf is not _EMPTY_BUF

    def __next__(self) -> _T_co:
        v = self._buf
        self._buf = next(self._real_it, _EMPTY_BUF)
        if v is _EMPTY_BUF:
            raise StopIteration()
        return v

主要的区别是has_next只是一个布尔表达式,也处理None值的迭代器。

将此添加到这里的测试和示例使用的要点。

我解决问题的方法是保留到目前为止迭代的对象数量的计数。我想通过调用实例方法遍历一个集合。因为我知道集合的长度,以及到目前为止计数的项的数量,所以我有效地使用了hasNext方法。

我的代码的一个简单版本:

class Iterator:
    # s is a string, say
    def __init__(self, s):
        self.s = set(list(s))
        self.done = False
        self.iter = iter(s)
        self.charCount = 0

    def next(self):
        if self.done:
            return None
        self.char = next(self.iter)
        self.charCount += 1
        self.done = (self.charCount < len(self.s))
        return self.char

    def hasMore(self):
        return not self.done

当然,这个例子是一个玩具,但您可以理解。这在无法获取可迭代对象长度的情况下不起作用,比如生成器等。

除了所有提到的StopIteration, Python的“for”循环只是做你想要的:

>>> it = iter("hello")
>>> for i in it:
...     print i
...
h
e
l
l
o

为了读取所有迭代,基于处理“StopIteration”执行的解决方法非常简单:

    end_cursor = False
    while not end_cursor:
        try:
            print(cursor.next())
        except StopIteration:
            print('end loop')
            end_cursor = True
        except:
            print('other exceptions to manage')
            end_cursor = True

在任意迭代器对象中尝试__length_hint__()方法:

iter(...).__length_hint__() > 0