재미를 위해 Aaron의 제안에 따라 lookahead 클래스 구현을 만들었습니다.
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까지).