PythonイテレータにはhasNext
メソッドがありませんか?
いいえ、そのような方法はありません。反復の終了は例外によって示されます。 ドキュメント を参照してください。
next(iterator, default_value)
を使用して、StopIteration
に代わるものがあります。
例:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
そのため、例外の方法が望ましくない場合は、None
またはイテレータの末尾のその他の事前に指定された値を検出できます。
本当に必要has-next
機能(Javaの参照実装からアルゴリズムを忠実に転写しているため、またはプロトタイプを書いているためwill終了したらJavaに簡単に転写する必要があります)、小さなラッパークラスで簡単に取得できます。例えば:
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
要求に応じ。
next(sel.it)
をビルトインとして使用するには、Python 2.6以上が必要です。古いバージョンのPythonを使用している場合は、代わりにself.it.next()
を使用します(使用例のnext(x)
についても同様)。 [[このノートは冗長であると合理的に思うかもしれません。Python 2.6は1年以上前から存在しますが、応答でPython 2.6の機能を使用する場合はそうではありません。 、一部のコメント作成者などは、それらがare 2.6の機能であることを指摘する義務があると感じています。したがって、このようなコメントを一度だけ回避しようとしています。
StopIterationのすべての言及に加えて、Python "for"ループは単にあなたが望むことをします:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
イテレータオブジェクトから__length_hint __()メソッドを試してください。
iter(...).__length_hint__() > 0
hasNext
はややStopIteration
例外に変換されます。例:
>>> it = iter("hello")
>>> it.next()
'h'
>>> it.next()
'e'
>>> it.next()
'l'
>>> it.next()
'l'
>>> it.next()
'o'
>>> it.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
StopIteration
docs: http://docs.python.org/library/exceptions.html#exceptions.StopIterationtee
イテレータを使用して、itertools.tee
を使用し、ティードイテレータでStopIteration
を確認できます。
いいえ。最も類似した概念は、おそらく StopIteration例外 です。
pythonには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」チェックが必要です。この内部チェックは非表示になるため、アイテムを取得して例外をキャッチし、スローされた場合はハンドラーを実行してテストする必要があります。これは不要なIMOの非表示です。
推奨される方法はStopIterationです。 tutorialspoint のフィボナッチの例を参照してください
#!usr/bin/python3
import sys
def fibonacci(n): #generator function
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(5) #f is iterator object
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
そのような質問/問題に対する良いアプローチは、dir(object/method/iterator/type/class/...)にあるものをチェックすることです
dir(iterator)
が__length_hint__
を返すことがわかります
iterator.__length_hint__()
は、反復が終了するまで正です。
それでおしまい。