Create a generator that yields values from any number of inner generators

核能气质少年 提交于 2019-12-19 18:55:07

问题


I have a generator function generate which yields 5 random numbers one at a time. I need to be able to generate the numbers in two ways:

  1. Single generation, which means a single output of generate function
  2. Multiple generation, which means multiple execution of generate and yielding all the results together as a single (merged) flow

For that I wrote another function get_resource, which calls generate either once or using itertools.chain to run the generators one after another, but transparently to the caller.

My goal is to use get_resource function and produce the results in the same format (one list of numbers), regardless of single/multiple generations.

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]))

It prints:

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

While I need it to print:

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

I use python2.7


回答1:


you should use itertools.chain.from_iterable

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



回答2:


You can specify generator delegation using yield from starting with python-3.3+.

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()

Now,

>>> list(get_resource([1, 2, 3]))
[46, 99, 97, 1, 42, 79, 69, 9, 45, 25, 77, 56, 54, 7, 41]


来源:https://stackoverflow.com/questions/48862536/create-a-generator-that-yields-values-from-any-number-of-inner-generators

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