只是为了好玩,我根据 Aaron 的建议创建了一个前瞻类的实现:
import itertools
class lookahead_chain(object):
def __init__(self, it):
self._it = iter(it)
def __iter__(self):
return self
def next(self):
return next(self._it)
def peek(self, default=None, _chain=itertools.chain):
it = self._it
try:
v = self._it.next()
self._it = _chain((v,), it)
return v
except StopIteration:
return default
lookahead = lookahead_chain
有了这个,以下将起作用:
>>> t = lookahead(xrange(8))
>>> list(itertools.islice(t, 3))
[0, 1, 2]
>>> t.peek()
3
>>> list(itertools.islice(t, 3))
[3, 4, 5]
使用此实现,连续多次调用 peek 是一个坏主意......
在查看 CPython 源代码时,我发现了一种更短、更高效的更好方法:
class lookahead_tee(object):
def __init__(self, it):
self._it, = itertools.tee(it, 1)
def __iter__(self):
return self._it
def peek(self, default=None):
try:
return self._it.__copy__().next()
except StopIteration:
return default
lookahead = lookahead_tee
用法与上面相同,但您不会在这里为连续多次使用 peek 付出代价。通过多几行,您还可以在迭代器中查看多个项目(最多可用 RAM)。