Есть ли способ прекратить давать, когда генератор не закончил значения и все необходимые результаты были прочитаны? Я имею в виду, что генератор дает значения, даже не делая 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 - генератор - функции /

3
Tony Veijalainen 24 Июл 2010 в 15:42

4 ответа

Лучший ответ

Это лучшее, что я придумал, но он все равно выполняет нарезку дважды, чтобы найти длину, и нужно преобразовать число строк из разбиения в 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 по формуле повторения

0
Community 23 Май 2017 в 12:01

По аналогии с функцией take в Haskell вы можете создать «ограниченный» генератор на основе другого генератора:

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

Вы можете продвинуть эту идею с генератором "пока", "пока", ...

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

...

0
xtofl 25 Июл 2010 в 07:48

Как вы уже видели,

TypeError: 'generator' object is unsubscriptable

И то, как вы написали devtrue, не должно останавливаться. Если вам нужна эта способность, вы можете:

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

Или гораздо проще:

y = [True] * 5

Если вы сделаете бесконечный генератор, он будет генерировать бесконечно.

0
msw 24 Июл 2010 в 12:40

Вы можете вызвать 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
8
Ferdinand Beyer 24 Июл 2010 в 11:58