これに対する答えによれば question 、C#のyield breakはpythonで返すのと同等です。通常の場合、「return」は実際にジェネレーターを停止します。ただし、関数が何も返さない場合、空のイテレータではなくNoneを取得します。これは、C#のyield breakによって返されます
def generate_nothing():
return
for i in generate_nothing():
print i
typeError: 'NoneType'オブジェクトは反復不可能です。しかし、戻る前に決して実行しないyieldを追加すると、この関数は期待したものを返します。
def generate_nothing():
if False: yield None
return
動作しますが、有線のようです。誰がより良いアイデアを持っていますか?
おかげで、
def generate_nothing():
return
yield
これを処理するための良い方法は、 StopIteration を上げることです。これは、イテレータに何も生成する余地がなく、next()
が呼び出されたときに発生します。これにより、ループ内で何も実行されずにforループから正常に抜け出します。
たとえば、タプル(0, 1, 2, 3)
重複するペアを取得したい((0, 1), (1, 2), (2, 3))
。私はそうすることができました:
def pairs(numbers):
if len(numbers) < 2:
raise StopIteration
for i, number in enumerate(numbers[1:]):
yield numbers[i], number
pairs
は、1個以下のリストを安全に処理します。
def generate_nothing():
return iter([])
面白い部分は、両方の関数が同じバイトコードを持っていることです。おそらく、バイトコードコンパイラがgenerator
キーワードを見つけたときにyield
に設定するフラグがあります。
>>> def f():
... return
>>> def g():
... if False: yield
#in Python2 you can use 0 instead of False to achieve the same result
>>> from dis import dis
>>> dis(f)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>> dis(g)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE