条件に一致する反復可能オブジェクトから最初の項目を取得する 質問する

条件に一致する反復可能オブジェクトから最初の項目を取得する 質問する

条件に一致するリストから最初の項目を取得したいと思います。結果のメソッドがリスト全体を処理しないことが重要です。リスト全体は非常に大きくなる可能性があります。たとえば、次の関数が適切です。

def first(the_iterable, condition = lambda x: True):
    for i in the_iterable:
        if condition(i):
            return i

この関数は次のように使用できます。

>>> first(range(10))
0
>>> first(range(10), lambda i: i > 3)
4

しかし、これを実行できる良い組み込み/ワンライナーを思いつきません。必要がない限り、この関数をコピーしたくありません。条件に一致する最初の項目を取得する組み込みの方法はありますか?

ベストアンサー1

Python 2.6+ および Python 3:

StopIteration一致する要素が見つからない場合に例外を発生させる場合:

next(x for x in the_iterable if x > 3)

default_value代わりに(例None) を返したい場合:

next((x for x in the_iterable if x > 3), default_value)

この場合、ジェネレータ式の周囲に追加の括弧が必要であることに注意してください。ジェネレータ式が唯一の引数ではない場合は常に括弧が必要になります。

ほとんどの回答は、next組み込みなので、何らかの不可解な理由で、Python バージョンの問題については言及せずに、バージョン 2.5 以前に 100% 焦点を当てているものと推測します (ただし、組み込みについて言及している回答nextではその言及が見られないため、自分で回答を提供する必要があると考えました。少なくとも、「正しいバージョン」の問題は、この方法で記録に残ります;-)。

Python <= 2.5

.next()StopIterationイテレータが直ちに終了した場合、つまり、あなたのユースケースでは、イテレータ内に条件を満たす項目がない場合、イテレータの メソッドは直ちに を発生させます。気にしない場合 (つまり、条件を満たす項目が少なくとも 1 つある.next()ことがわかっている場合) は、 (genexp に最適、Python 2.6 以降では組み込みの行)を使用しますnext

気にするのであれば、質問で最初に示したように関数でラップするのが最善のようです。提案した関数の実装は問題ありませんが、さまざまな回答で示唆されているように、関数の本体としてitertoolsfor...: breakループ、genexp、またはを使用することもできますtry/except StopIteration。これらの代替案のいずれにもあまり付加価値がないので、最初に提案された非常に単純なバージョンを選択します。

おすすめ記事