このzip
は、最初に出されたアイテムを食べるので、それは良い考えではありません。
ジェネレータは、必要なときに取得して保持することによって、降伏するアイテムを検出できます。次のクラスは、あなたがそうするのを助けるでしょう。
必要に応じて、イテレータから項目を取得して保持します。
空白を要求された場合(if myiterwatch: ...
)、取得できるかどうかを取得して返します。
次の項目について質問された場合、取得した項目または新しい項目が戻されます。
class IterWatch(object):
def __init__(self, it):
self.iter = iter(it)
self._pending = []
@property
def pending(self):
try:
if not self._pending:
# will raise StopIteration if exhausted
self._pending.append(next(self.iter))
except StopIteration:
pass # swallow this
return self._pending
def next(self):
try:
return self.pending.pop(0)
except IndexError:
raise StopIteration
__next__ = next # for Py3
def __iter__(self): return self
def __nonzero__(self):
# returns True if we have data.
return not not self.pending
# or maybe bool(self.pending)
__bool__ = __nonzero__ # for Py3
これは非常に一般的な方法で問題を解決します。あなたはちょうどテストするイテレータを持っている場合は、イテレータa
が消耗されている場合、あなたは
guard = object()
result = return_generator()
if next(result, guard) is not guard:
print 'Yes, the generator did generate something!'
next(a, b)
戻りb
を使用することができます。だから私たちの場合にガードを返すなら、それは何かを生成しなかった、そうでなければそれをした。
しかし、あなたのzip()
アプローチは、同様に完全に有効である...ここ
* sigh *今日は本当の脳のフェードがあります。私はこの質問に適任者を熱望しています。 :P – detly
@detlyいいえ、発電機を消費しません。降伏してテストするときに印刷するジェネレータを書くことができます。 – satoru
ええ、私はそれをテストしたときに気付いた(それは最初のアイテムを消費するものの)。だから私は元のコメントを削除したのです:P – detly