3

ジェネレーターが値を終了せず、必要なすべての結果が読み取られたときに、生成を停止する方法はありますか? つまり、ジェネレーターは StopIteration を実行せずに値を提供しています。

たとえば、これは止まらない: (改訂版)

from random import randint
def devtrue():
    while True:
        yield True

answers=[False for _ in range(randint(100,100000))]
answers[::randint(3,19)]=devtrue()
print answers

このコードを見つけましたが、この場合の適用方法はまだわかりません: http://code.activestate.com/recipes/576585-lazy-recursive-generator-function/

4

4 に答える 4

8

close()ジェネレーター オブジェクトを呼び出すことができます。このようにして、ジェネレーター内で例外が発生し、そのメソッドをGeneratorExitさらに呼び出すと、次のように発生します。next()StopIteration

>>> def test():
...     while True:
...         yield True
... 
>>> gen = test()
>>> gen
<generator object test at ...>
>>> gen.next()
True
>>> gen.close()
>>> gen.next()
Traceback (most recent call last):
  ...
StopIteration
于 2010-07-24T11:52:23.920 に答える
0

Haskellの関数と同様に、take別のジェネレーターに基づいて「限定された」ジェネレーターを構築できます。

def take(n,gen):
    '''borrowed concept from functional languages'''
togo=n
while togo > 0:
    yield gen.next()
    togo = togo - 1

def naturalnumbers():
    ''' an unlimited series of numbers '''
    i=0
    while True:
        yield i
        i=i+1

for n in take(10, naturalnumbers() ):
   print n

「until」ジェネレーター、「while」などを使用して、このアイデアをさらに進めることができます。

def gen_until( condition, gen ):
   g=gen.next()
   while( not condition(g) ):
      yield g
      g=gen.next()

そして、それを次のように使用します

for i in gen_until( lambda x: x*x>100, naturalnumbers() ):
  print i

...

于 2010-07-25T07:29:21.017 に答える
0

これは私が思いついた最善の方法ですが、長さを見つけるためにスライスを 2 回行い、文字列番号を分割から int に変換する必要があります。

from time import clock
from random import randint
a=[True for _ in range(randint(1000000,10000000))]
spacing=randint(3,101)
t=clock()
try:
    a[::spacing]=[False]
except ValueError as e:
    a[::spacing]=[False]*int(e.message.rsplit(' ',1)[-1])

print spacing,clock()-t

# baseline

t=clock()
a[::spacing]=[False]*len(a[::spacing])
print 'Baseline:',spacing,clock()-t

素数ふるいにかけてみますが、再帰式から長さの計算を行うよりも速くはなりそうにありません。 漸化式による純粋な Python プライム シーブの改善

于 2010-07-24T22:00:21.927 に答える
0

すでに見てきたように、

TypeError: 'generator' object is unsubscriptable

そして、あなたが書いた方法devtrueは止まらないはずです。その容量が必要な場合は、次のことができます。

def bounded_true(count)
   while count > 0:
       yield True
       count -= 1

またははるかに簡単に:

y = [True] * 5

無限ジェネレーターを作れば無限に生成されます。

于 2010-07-24T12:04:09.460 に答える