3

特定の式に従って数値を出し続けるジェネレーターがあります。議論のために、これが関数であるとしましょう:

# this is not the actual generator, just an example
def Generate():
    i = 0
    while 1:
        yield i
        i+=1       

次に、そのジェネレーターから、特定のしきい値を下回っている数値のリストを取得したいと考えています。私はこれを行うためのpythonicな方法を見つけようとしています。関数定義を編集したくありません。カットオフを条件として while ループを使用できることはわかっていますが、もっと良い方法があるかどうか疑問に思っています。私はこれを試してみましたが、すぐにうまくいかない理由に気づきました。

l = [x for x in Generate() x<10000] # will go on infinitely

これを行う正しい方法はありますか。

ありがとう

4

6 に答える 6

13

itertools別のイテレータを作成するソリューション:

from itertools import takewhile
l = takewhile(lambda x: x < 10000, generate())

list()リストが必要な場合は、次のようにラップします。

l = list(takewhile(lambda x: x < 10000, generate()))

または、リストが必要で、車輪の発明が好きな場合:

l = []
for x in generate():
    if x < 10000:
        l.append(x)
    else:
        break
于 2013-02-01T19:49:08.703 に答える
0

itertools.takewhile述語を満たさないアイテムに遭遇するまでのみ機能します。おそらく順序付けられていない iterable からすべての値を返す必要がある場合は、itertools.ifilterfor Python 2.x のように使用することをお勧めします

from itertools import ifilter
f = ifilter(lambda x: x < 400, gen())
f.next()

これにより、0 から 400 の間のランダムな整数を生成するジェネレーターが期待どおりにフィルター処理されました。

FWIWitertools.ifilterは Python 3.x で非推奨になり、filter()繰り返しの構文がわずかに異なる組み込みが優先されました。

f = filter(lambda x: x < 400, gen())
next(f)
于 2013-02-02T00:00:54.663 に答える
0

ジェネレーターを別のジェネレーター内にラップします。

def no_more_than(limit):
    def limiter(gen):
        for item in gen:
            if item > limit:
                break
            yield item
    return limiter

def fib():
    a,b = 1,1
    while 1:
        yield a
        a,b = b,a+b


cutoff_at_100 = no_more_than(100)
print list(cutoff_at_100(fib()))

版画:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
于 2013-02-01T21:04:48.533 に答える
-1

無限ジェネレーターにカウンターを使用するだけです。

gen=Generate()        # your generator function example
l=[gen.next() for i in range(100)]

ただし、これはジェネレーターであるため、ジェネレーター式を使用します。

seq=(gen.next() for i in xrange(100))  #need x in xrange in Python 2.x; 3.x use range

編集

OK、次にコントローラーを使用します。

def controler(gen,limit):
    n=gen.next()
    while n<limit:
        yield n
        n=gen.next()

seq=[i for i in controler(Generate(),100)]
于 2013-02-01T19:55:08.567 に答える
-1

Generate()と置き換えますxrange(10000)

于 2013-02-01T23:51:45.513 に答える