Python 迭代器有
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
以查看是否已到达迭代器的末尾,如果您不想使用异常方式进行操作。
如果您的可迭代对象可能包含None
值,则必须定义一个哨兵值并检查它:
>>> sentinel = object()
>>> a = iter([None, 1, 2])
>>> elem = next(a, sentinel)
>>> if elem is sentinel:
... print('end')
...
>>>
sentinel = object()
,next(iterator, sentinel)
和is
运算符进行测试。 - sam boosalisunittest.mock.sentinel
对象,这样你就可以编写明确的 next(a, sentinel.END_OF_ITERATION)
,然后检查 if next(...) == sentinel.END_OF_ITERATION
。 - ClementWalter没有这样的方法。迭代结束是通过异常来指示的。请查看文档。
unnext()
方法可以在调用next()
检查元素是否存在后将第一个元素放回,则我会接受try catch解决方案。 - Giorgioyield
),就无法确定另一个元素是否存在。当然,编写一个适配器来存储next()
的结果并提供has_next()
和move_next()
也不难。注意保持原文意思不变,同时让翻译更加通俗易懂。 - avakarhasNext()
方法(在成功时生成、缓存并返回true,或者在失败时返回false)。然后,hasNext()
和next()
都将依赖于一个共同的底层getNext()
方法和缓存项。如果提供适配器很容易实现,我真的看不出为什么next()
不应该在标准库中。 - Giorgionext()
和 hasNext()
方法的库,而不仅仅是假设的Python库)。因此,如果流中的内容取决于何时读取元素,则next()
和hasNext()
变得棘手。 - Giorgio不可以,但是你可以实现自己的可迭代包装类来实现:
from collections.abc import Iterator
class hn_wrapper(Iterator):
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
has_next
ж–№жі•зҡ„жңҖзіҹзі•зҡ„еҺҹеӣ гҖӮPythonзҡ„и®ҫи®ЎдҪҝеҫ—ж— жі•дҪҝз”Ёfilter
жЈҖжҹҘж•°з»„жҳҜеҗҰеҢ…еҗ«дёҺз»ҷе®ҡи°“иҜҚеҢ№й…Қзҡ„е…ғзҙ гҖӮPythonзӨҫеҢәзҡ„еӮІж…ўе’Ңзӣ®е…үзҹӯжө…д»ӨдәәйңҮжғҠгҖӮ - Jonathan Castmap
和any
而不是filter
,但是你可以使用SENTINEL = object();next(filter(predicate,arr),SENTINEL)不是SENTINEL
,或者忘记一个SENTINEL
并且只是使用try:except
捕获StopIteration
。 - juanpa.arrivillaganext()
一样实现 hasnext()
,即将方法重命名为 hn_wrapper.__hasnext__()
,然后定义一个顶层函数来调用该方法:def hasnext(iterable): return iterable.__hasnext__()
。 - user3064538除了所有关于StopIteration
的提及外,Python for
循环也能实现您想要的功能:
>>> it = iter('hello')
>>> for i in it:
... print(i)
...
h
e
l
l
o
尝试使用任何迭代器对象的__length_hint__()方法:
iter(...).__length_hint__() > 0
__init__
和 __main__
这样的命名方式?在我看来,无论你如何辩解,这都有点混乱。 - user1363990itertools.tee
对迭代器进行复制,并检查复制后的迭代器是否出现 StopIteration
。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不是。最相似的概念很可能是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
hasNext()
和Next()
。Python通过在生成器结束时抛出异常来避免这种情况。而next(gen, default_value)
习语允许您消除该异常,而无需使用try..except
。) - smci