Python迭代器有has_next方法吗?


当前回答

非常有趣的问题,但是这个“hasnext”的设计已经放进了leetcode: https://leetcode.com/problems/iterator-for-combination/

这是我的实现:

class CombinationIterator:

def __init__(self, characters: str, combinationLength: int):
    from itertools import combinations
    from collections import deque
    self.iter = combinations(characters, combinationLength)
    self.res = deque()


def next(self) -> str:
    if len(self.res) == 0:
        return ''.join(next(self.iter))
    else:
        return ''.join(self.res.pop())


def hasNext(self) -> bool:
    try:
        self.res.insert(0, next(self.iter))
        return True
    except:
        return len(self.res) > 0

其他回答

也可以实现一个helper生成器,它包装任何迭代器,并回答问题,如果它有next值:

在网上试试!

def has_next(it):
    first = True
    for e in it:
        if not first:
            yield True, prev
        else:
            first = False
        prev = e
    if not first:
        yield False, prev

for has_next_, e in has_next(range(4)):
    print(has_next_, e)

输出:

True 0
True 1
True 2
False 3

该方法的主要缺点(可能也是唯一的缺点)是它会多预读一个元素,对于大多数任务来说,它是完全可以的,但对于某些任务,它可能是不允许的,特别是如果has_next()的用户没有意识到这种预读逻辑,可能会误用它。

上面的代码也适用于无限迭代器。

实际上,对于所有的情况下,我曾经编写这样的has_next()是完全足够的,没有造成任何问题,事实上是非常有用的。你只需要知道它的预读逻辑。

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

建议的方法是StopIteration。 请参阅tutorialspoint中的斐波那契示例

#!usr/bin/python3

import sys
def fibonacci(n): #generator function
   a, b, counter = 0, 1, 0
   while True:
      if (counter > n): 
         return
      yield a
      a, b = b, a + b
      counter += 1
f = fibonacci(5) #f is iterator object

while True:
   try:
      print (next(f), end=" ")
   except StopIteration:
      sys.exit()

除了所有提到的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