81

Python 組み込み関数にandfirst(iterable)に似たものがない理由があるかどうか疑問に思っています (stdlib モジュールのどこかに隠れている可能性がありますが、 には表示されません)。短絡発生器の評価を実行して、不必要な(そして潜在的に無限の数の)操作を回避できるようにします。すなわちany(iterable)all(iterable)itertoolsfirst

def identity(item):
    return item

def first(iterable, predicate=identity):
    for item in iterable:
        if predicate(item):
            return item
    raise ValueError('No satisfactory value found')

このようにして、次のように表現できます。

denominators = (2, 3, 4, 5)
lcd = first(i for i in itertools.count(1)
    if all(i % denominators == 0 for denominator in denominators))

list(generator)[0]ジェネレーターは終了しないため、明らかにその場合はできません。

または、照合する正規表現がたくさんある場合 (それらがすべて同じgroupdictインターフェースを持っている場合に便利です):

match = first(regex.match(big_text) for regex in regexes)

list(generator)[0]肯定的な一致を回避して短絡することで、不要な処理を大幅に節約できます。

4

6 に答える 6

50

Python 2では、反復子がある場合は、そのnextメソッドを呼び出すだけです。何かのようなもの:

>>> (5*x for x in xrange(2,4)).next()
10

Python 3では、nextビルトインをイテレータで使用できます。

>>> next(5*x for x in range(2,4))
10
于 2009-07-03T00:18:22.677 に答える
19
于 2013-04-23T16:11:47.973 に答える
6

itertools には「スライス」イテレータがあります。Python で使い慣れたスライス操作をエミュレートします。あなたが探しているのは、これに似たものです:

myList = [0,1,2,3,4,5]
firstValue = myList[:1]

イテレータに itertools を使用した同等のもの:

from itertools import islice
def MyGenFunc():
    for i in range(5):
        yield i

mygen = MyGenFunc()
firstValue = islice(mygen, 0, 1)
print firstValue 
于 2013-09-03T10:30:54.447 に答える
6

あなたの質問にはあいまいなところがあります。firstの定義と正規表現の例は、ブール値のテストがあることを意味します。しかし、分母の例には明示的に if 節があります。したがって、各整数がたまたま true になるのは偶然です。

next と itertools.ifilter を組み合わせると、必要なものが得られるようです。

match = next(itertools.ifilter(None, (regex.match(big_text) for regex in regexes)))
于 2009-07-03T00:38:09.017 に答える
4

Haskell は、関数 (または技術的 takeには部分関数) として、あなたが説明したものを利用します。Python Cookbookには、Haskellの 、、および と同じ機能を実行するジェネレーター ラッパーが記述されています。take 1taketakeWhiledrop

しかし、なぜそれが組み込みではないのかについては、あなたの推測は私のものと同じです。

于 2009-07-03T00:22:29.300 に答える