質問

私はPythonの for ... else構文の大ファンです-どれくらいの頻度で適用できるか、そしてコードをどれだけ効果的に簡素化できるかは驚くべきことです。

しかし、ジェネレータでそれを使用する良い方法を見つけていません。例えば:

def iterate(i):
    for value in i:
        yield value
    else:
        print 'i is empty'

上記の例では、 i が空の場合にのみ print ステートメントが実行されるようにします。ただし、 else break および return のみを尊重するため、 i の長さに関係なく、常に実行されます。

この方法で for ... else を使用することが不可能な場合、何も得られない場合にのみ print ステートメントが実行されるようにする最善の方法は何ですか?

役に立ちましたか?

解決

ジェネレーターの定義を壊しているため、反復が完了するとStopIteration例外がスローされます(ジェネレーター関数のreturnステートメントによって自動的に処理されます)

だから:

def iterate(i):
    for value in i:
        yield value
    return

呼び出し元のコードが空のイテレータのケースを処理できるようにするのに最適:

count = 0
for value in iterate(range([])):
    print value
    count += 1
else:
    if count == 0:
        print "list was empty"

上記をよりクリーンに行う方法かもしれませんが、それはうまく動作するはずであり、一般的な「リストのようなイテレータの処理」トラップのいずれにも該当しません。

他のヒント

これを行うにはいくつかの方法があります。常に Iterator を直接使用できます:

def iterate(i):
    try:
        i_iter = iter(i)
        next = i_iter.next()
    except StopIteration:
        print 'i is empty'
        return

    while True:
        yield next
        next = i_iter.next()

しかし、引数 i に何を期待するかについてもっと知っているなら、もっと簡潔にすることができます:

def iterate(i):
    if i:  # or if len(i) == 0
        for next in i:
            yield next
    else:
        print 'i is empty'
        raise StopIteration()

以前の回答の一部をまとめると、次のように解決できます:

def iterate(i):
    empty = True
    for value in i:
        yield value
        empty = False

    if empty:
        print "empty"

したがって、実際には" else"はありません。関連する条項。

ご指摘のとおり、 for..else break のみを検出します。そのため、何かを探してから停止する場合にのみ適用されます。

ジェネレータではないので目的に当てはまりませんが、すべての要素を停止せずに処理したいので(すべての要素を生成したいので、それはポイントではありません)。

つまりジェネレーターであるかどうかにかかわらず、Berのソリューションのようにブール値が本当に必要です。

  
    

for ... elseをこの方法で使用することが不可能な場合、printステートメントは何も生成されない場合にのみ実行されるようにするための最善のアプローチは何ですか?

  

考えられる最大:


>>> empty = True
>>> for i in [1,2]:
...     empty = False
... if empty:
...     print 'empty'
...
>>>
>>>
>>> empty = True
>>> for i in []:
...     empty = False
... if empty:
...    print 'empty'
...
empty
>>>

単純なif-elseはどうですか?

def iterate(i):
    if len(i) == 0: print 'i is empty'
    else:
        for value in i:
            yield value
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top