web-dev-qa-db-ja.com

ブレークインのPython

これに対する答えによれば 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

動作しますが、有線のようです。誰がより良いアイデアを持っていますか?

おかげで、

49
Sonic Lee
def generate_nothing():
    return
    yield
45
ninjagecko

これを処理するための良い方法は、 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個以下のリストを安全に処理します。

45
Sam Simmons
def generate_nothing():
    return iter([])
6
phihag

面白い部分は、両方の関数が同じバイトコードを持っていることです。おそらく、バイトコードコンパイラが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
1
JBernardo