Python迭代器有has_next方法吗?


当前回答

为了读取所有迭代,基于处理“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

其他回答

不。最类似的概念很可能是StopIteration异常。

不,没有这样的方法。迭代的结束是由StopIteration表示的(更多信息在这里)。


这遵循了python原则EAFP(请求原谅比请求许可更容易)。has_next方法将遵循LBYL原则(三思而后行),并与python的核心原则相矛盾。

这篇有趣的文章更详细地解释了这两个概念。

你可以使用itertools来tee迭代器。在teed迭代器上检查StopIteration。

也许只有我这么想,但虽然我喜欢https://stackoverflow.com/users/95810/alex-martelli的答案,但我发现这个更容易读:

from collections.abc import Iterator  # since python 3.3 Iterator is here

class MyIterator(Iterator):  # need to subclass Iterator rather than object
  def __init__(self, it):
    self._iter = iter(it)
    self._sentinel = object()
    self._next = next(self._iter, self._sentinel)
    
  def __iter__(self): 
    return self
  
  def __next__(self):        # __next__ vs next in python 2
    if not self.has_next():
      next(self._iter)  # raises StopIteration

    val = self._next
    self._next = next(self._iter, self._sentinel)
    return val
  
  def has_next(self):
    return self._next is not self._sentinel

为了读取所有迭代,基于处理“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