代码之家  ›  专栏  ›  技术社区  ›  Tony Veijalainen

屈服直到所有需要的值都屈服,有没有办法让slice变得懒惰

  •  3
  • Tony Veijalainen  · 技术社区  · 15 年前

    当生成器未完成值并且所有需要的结果都已读取时,是否有方法停止生成?我的意思是生成器在不做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 回复  |  直到 15 年前
        1
  •  8
  •   Ferdinand Beyer    15 年前

    你可以打电话 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
    
        2
  •  0
  •   msw    15 年前

    如你所见,

    TypeError: 'generator' object is unsubscriptable
    

    还有你的写作方式 devtrue

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

    或者更简单地说:

    y = [True] * 5
    

        3
  •  0
  •   xtofl Adam Rosenfield    15 年前

    类似于 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
    

        4
  •  0
  •   Community Mohan Dere    9 年前

    这是我想到的最好的方法,但它仍然会进行两次切片以找到长度,并且需要将字符串编号从拆分转换为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
    

    Improving pure Python prime sieve by recurrence formula