Search code examples
pythonpython-3.xgeneratorpython-decorators

Changing a generator with another function - Python 3.x


I want to change the behavior of the generator below so that it only yields even numbers. How can I do this?

I'm aware that there simpler, clever ways to do this. This is a contrived HR challenge, where the

The change_generator function that I wrote does not yield the desired output. I can only change change_generator.

I cannot change positive_integers_generator() nor the for loop below.

Can I solve this with a decorator?

#can't change the body of this function
def positive_integers_generator():
    n = 1
    while True:
        x = yield n
        if x is not None:
            n = x
        else:
            n += 1

# can only change this function            
def change_generator(generator, n):
  for i in generator:
    if i%2 == 0:
      yield(i)



# can't change this code either
# should print 1, 2, 4, 6, 8
g = positive_integers_generator() 
for _ in range(5):
    n = next(g)
    print(n)
    change_generator(g, n)

Solution

  • You can use the built in function filter

    even_numbers_generator = filter(lambda n: n % 2 == 0, positive_integers_generator())
    

    Or a generator expression.

    even_numbers_generator = (n for n in positive_integers_generator() if n % 2 == 0)
    

    Or itertools.count from the standard library:

    even_numbers_generator = itertools.count(start=2, step=2)
    

    But if you only can change the change_generator function, the "correct answer" to the challenge probably involves using generator.send()

    # can only change this function            
    def change_generator(generator, n):
        if n % 2 == 0:
            generator.send(n + 1)