Yielding until all needed values are yielded, is there way to make slice to become lazy

假如想象 提交于 2019-12-01 08:32:06

You can call close() on the generator object. This way, a GeneratorExit exception is raised within the generator and further calls to its next() method will raise 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

As you have already seen,

TypeError: 'generator' object is unsubscriptable

And the way you have written devtrue it shouldn't stop. If you need that capacity you could:

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

or far more simply:

y = [True] * 5

If you make an infinite generator, it will generate infinitely.

In analogy with the take function in Haskell, you can build a 'limited' generator based upon another generator:

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

You can further this idea with an "until" generator, a "while", ...

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

And use it like

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

...

Tony Veijalainen

This is best I came up with, but it does still the slicing twice to find the length and need to convert string number from splitting to 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

I will try it to my prime sieve, but it is likely not to be faster than doing the length arithmetic from recurrence formula. Improving pure Python prime sieve by recurrence formula

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!