Python迭代器有has_next方法吗?
当前回答
如果您确实需要一个has-next功能,那么使用一个小包装器类很容易获得它。例如:
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
是必需的。
Note that the use of next(sel.it) as a built-in requires Python 2.6 or better; if you're using an older version of Python, use self.it.next() instead (and similarly for next(x) in the example usage). [[You might reasonably think this note is redundant, since Python 2.6 has been around for over a year now -- but more often than not when I use Python 2.6 features in a response, some commenter or other feels duty-bound to point out that they are 2.6 features, thus I'm trying to forestall such comments for once;-)]]
===
对于Python3,您将进行以下更改:
from collections.abc import Iterator # since python 3.3 Iterator is here
class hn_wrapper(Iterator): # need to subclass Iterator rather than object
def __init__(self, it):
self.it = iter(it)
self._hasnext = None
def __iter__(self):
return self
def __next__(self): # __next__ vs next in python 2
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
其他回答
也可以实现一个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()是完全足够的,没有造成任何问题,事实上是非常有用的。你只需要知道它的预读逻辑。
不,没有这样的方法。迭代的结束由异常表示。请参见文档。
我认为当你想要某种has_next功能时,有一些有效的用例,在这种情况下,你应该用定义了has_next的迭代器来装饰迭代器。
结合这个问题的答案的概念,这里是我的实现,这对我来说是一个很好的简洁的解决方案(python 3.9):
_EMPTY_BUF = object()
class BufferedIterator(Iterator[_T]):
def __init__(self, real_it: Iterator[_T]):
self._real_it = real_it
self._buf = next(self._real_it, _EMPTY_BUF)
def has_next(self):
return self._buf is not _EMPTY_BUF
def __next__(self) -> _T_co:
v = self._buf
self._buf = next(self._real_it, _EMPTY_BUF)
if v is _EMPTY_BUF:
raise StopIteration()
return v
主要的区别是has_next只是一个布尔表达式,也处理None值的迭代器。
将此添加到这里的测试和示例使用的要点。
我相信python只有next(),根据文档,如果没有更多的元素,它就会抛出异常。
http://docs.python.org/library/stdtypes.html#iterator-types
使用next(迭代器,default_value)可以替代StopIteration。
For exapmle:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
因此,如果你不想用异常方式,你可以为None或其他预先指定的值检测迭代器的end。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录