Answers:
不,没有这样的方法。迭代结束由异常指示。请参阅文档。
unnext()
方法可以通过调用来检查第一个元素是否存在,那么我将接受try catch解决方案next()
。
yield
)。当然,编写存储next()
并提供has_next()
和的结果的适配器并不难move_next()
。
hasNext()
方法(成功时生成,缓存并返回true,失败时返回false)。然后这两个hasNext()
和next()
将取决于一个普遍的根本getNext()
方法和缓存项。我真的不明白next()
,如果实现提供它的适配器非常容易,为什么不应该将它放在标准库中。
next()
和hasNext()
方法,而不仅仅是一个假设的Python库)。所以,是的,next()
而且hasNext()
变得非常棘手,如果被扫描的数据流的内容取决于当读取元素。
StopIteration
使用可以替代next(iterator, default_value)
。
例如:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
因此None
,如果您不想使用异常方法,则可以为迭代器的末尾检测或其他预先指定的值。
sentinel = object()
并next(iterator, sentinel)
进行测试is
。
unittest.mock.sentinel
对象,它允许您编写一个明确的对象,next(a, sentinel.END_OF_ITERATION)
然后if next(...) == sentinel.END_OF_ITERATION
如果你真的需要一个has-next
功能(因为你只是忠实地从Java中的参考实现转录的算法,比方说,还是因为你写一个原型,将需要轻松转录到Java时,它的完成),它很容易可以通过一些包装类来获得它。例如:
class hn_wrapper(object):
def __init__(self, it):
self.it = iter(it)
self._hasnext = None
def __iter__(self): return self
def next(self):
if self._hasnext:
result = self._thenext
else:
result = next(self.it)
self._hasnext = None
return result
def hasnext(self):
if self._hasnext is None:
try: self._thenext = next(self.it)
except StopIteration: self._hasnext = False
else: self._hasnext = True
return self._hasnext
现在像
x = hn_wrapper('ciao')
while x.hasnext(): print next(x)
发出
c
i
a
o
按要求。
请注意,将next(sel.it)
用作内置功能需要Python 2.6或更高版本;如果您使用的是旧版本的Python,请self.it.next()
改用(和next(x)
示例用法类似)。[[[您可能会合理地认为此注释是多余的,因为Python 2.6已经存在了一年多了-但是当我在响应中使用Python 2.6功能时,很多评论者或其他人有责任指出它们是 2.6功能,因此,我试图一次阻止所有此类评论;-)]]
has_next
方法的最糟糕的理由。Python的设计使得无法filter
检查数组是否包含与给定谓词匹配的元素。Python社区的傲慢和短视令人震惊。
TypeError: iter() returned non-iterator
map
和any
来代替filter
,但是您可能会使用SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINEL
或忘记一个,SENTINEL
而只是使用try: except
并捕获StopIteration
。
从任何迭代器对象尝试__length_hint __()方法:
iter(...).__length_hint__() > 0
__init__
和 __main__
?恕我直言,无论您试图为其辩护,都有些混乱。
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
docs:http : //docs.python.org/library/exceptions.html#exceptions.StopIteration我相信python只是具有next(),根据文档,它抛出一个异常是没有更多的元素。
以下是促使我进行搜索的用例:
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
try:
x = next(fi)
except StopIteration:
fi = iter(f)
x = next(fi)
self.a[i] = x
在hasnext()可用的地方,一个可以做
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
if not hasnext(fi):
fi = iter(f) # restart
self.a[i] = next(fi)
对我来说更干净 显然,您可以通过定义实用程序类来解决问题,但是接下来会发生二十多种不同的,几乎等效的解决方法,每个解决方法都有其怪癖,并且,如果您想重复使用使用不同解决方法的代码,则必须在您的单个应用程序中具有多个接近相等的值,或者四处浏览并重写代码以使用相同的方法。“一次做就做好”的格言非常失败。
此外,迭代器本身需要进行内部“ hasnext”检查,以查看是否需要引发异常。然后隐藏此内部检查,以便需要通过尝试获取项目,捕获异常并在抛出异常时运行处理程序来对其进行测试。这是不必要的隐藏IMO。
建议的方法是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()
我解决问题的方法是保持到目前为止迭代对象的数量。我想使用对实例方法的调用来遍历集合。由于我知道集合的长度以及到目前为止已计算的项目数,因此我有效地有了一种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
当然,示例是一个玩具,但是您知道了。在无法获得迭代器长度的情况下(例如生成器等),这将不起作用。