问题:在Python迭代器中具有hasNext?
Python迭代器没有hasNext
方法吗?
回答 0
不,没有这样的方法。迭代结束由异常指示。请参阅文档。
回答 1
StopIteration
使用可以替代next(iterator, default_value)
。
例如:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
因此None
,如果您不想使用异常方法,则可以为迭代器的末尾检测或其他预先指定的值。
回答 2
如果你真的需要一个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功能,因此,我试图一次阻止所有此类评论;-)]]
回答 3
除了提到StopIteration之外,Python的“ for”循环还可以满足您的要求:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
回答 4
从任何迭代器对象尝试__length_hint __()方法:
iter(...).__length_hint__() > 0
回答 5
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中的迭代器和生成器的一些文章:http : //www.ibm.com/developerworks/library/l-pycon.html
回答 6
您可以tee
使用itertools.tee
和进行迭代,并检查StopIteration
teed迭代器。
回答 7
否。最相似的概念很可能是StopIteration异常。
回答 8
我相信python只是具有next(),根据文档,它抛出一个异常是没有更多的元素。
回答 9
以下是促使我进行搜索的用例:
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。
回答 10
建议的方法是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()
回答 11
我解决问题的方法是保持到目前为止迭代对象的数量。我想使用对实例方法的调用来遍历集合。由于我知道集合的长度以及到目前为止已计算的项目数,因此我有效地有了一种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
当然,示例是一个玩具,但是您知道了。在无法获得迭代器长度的情况下(例如生成器等),这将不起作用。