创建一个生成器,从任意数量的内部生成器生成值

时间:2018-02-19 09:03:26

标签: python generator

我有一个生成器函数generate,它一次产生一个随机数。我需要能够以两种方式生成数字:

  1. 单次生成,表示generate函数的单个输出
  2. 多代,意味着多次执行generate并将所有结果合并为一个(合并)流
  3. 为此我写了另一个函数get_resource,它调用generate一次或使用itertools.chain一个接一个地运行生成器,但对调用者来说是透明的。

    我的目标是使用get_resource函数并以相同的格式(一个数字列表)生成结果,而不管单个/多代。

    import itertools
    import random
    
    
    def get_resource(values=None):
        def resource_generator():
            if values:
                # run a generator for every value
                return itertools.chain(generate(value) for value in values)
            else:
                return generate('meh')
    
        return resource_generator()
    
    
    def generate(value):
        for _ in range(5):
            yield random.randint(1, 101)
    
    
    if __name__ == '__main__':
        # list() is used for convenience only, 
        # I still need the values one by one
        print list(get_resource())
        print list(get_resource([1, 2, 3]))
    

    打印:

    [63, 22, 87, 2, 54]
    [<generator object generate at 0x1089f7640>, <generator object generate at 0x1089f7690>, <generator object generate at 0x1089f76e0>]
    

    虽然我需要它来打印:

    [63, 22, 87, 2, 54]
    [63, 22, 87, 2, 54, 1, 58, 79, 89, 77, 94, 99, 30, 30, 4]
    

    我使用的是python2.7

2 个答案:

答案 0 :(得分:5)

您可以使用configurations { runtime.exclude group: "org.slf4j", module: "slf4j-log4j12" } 从python-3.3 +开始指定生成器委派。

yield from

现在,

def get_resource(values=None):
    def resource_generator():
        if values:
            for value in values:
                yield from generate(value)
        else:
            yield from generate(None)

    return resource_generator()

答案 1 :(得分:2)

你应该使用itertools.chain.from_iterable

return itertools.chain.from_iterable(generate(value) for value in values)