Python迭代器有has_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)
这对我来说更干净。显然,您可以通过定义实用程序类来解决这些问题,但接下来的情况是,您有20多种几乎等效的解决方法,每种方法都有各自的怪癖,如果您希望重用使用不同解决方法的代码,那么您必须在单个应用程序中有多个几乎等效的代码,或者四处挑选并重写代码以使用相同的方法。“只做一次,就把它做好”的格言很失败。
此外,迭代器本身需要有一个内部的“hasnext”检查,以查看是否需要引发异常。然后,这个内部检查被隐藏起来,因此需要通过尝试获取一个项、捕捉异常并在抛出异常时运行处理程序来测试它。在我看来,这是不必要的隐藏。
其他回答
我认为当你想要某种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值的迭代器。
将此添加到这里的测试和示例使用的要点。
除了所有提到的StopIteration, Python的“for”循环只是做你想要的:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
在任意迭代器对象中尝试__length_hint__()方法:
iter(...).__length_hint__() > 0
也许只有我这么想,但虽然我喜欢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”的设计已经放进了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
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录