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:
generate
functiongenerate
and yielding all the results together as a single (merged) flowFor 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
The done property of the generator object will be set to true and the value returned will be set to the value property of the generator object. All other yields will return undefined . If an error is thrown then also the execution of the generator will stop, yielding a generator itself.
If you want to return multiple values from a function, you can use generator functions with yield keywords. The yield expressions return multiple values. They return one value, then wait, save the local state, and resume again.
Generator function contains one or more yield statements. When called, it returns an object (iterator) but does not start execution immediately. Methods like __iter__() and __next__() are implemented automatically. So we can iterate through the items using next() .
Unless your generator is infinite, you can iterate through it one time only. Once all values have been evaluated, iteration will stop and the for loop will exit. If you used next() , then instead you'll get an explicit StopIteration exception.
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With