Search code examples
pythonpython-3.xyield

Yield usage in recursive manner


I was playing around with the yield and I made up a function that takes 3 numbers and a limit and computes them in a particular way (the computation is not important, but can be seen in the code below).

values = []

def compute(limit, a, b, c):
    if a <= limit:
        print("Got {}, {}, {}".format(a, b, c))
        values.append([a, b, c])
        compute(limit, b*c, a*c, a*b)
    else:
        print("Process ended")


compute(9999, 2, 3, 4)
print(values)

This works, and produces the output:

Got 2, 3, 4
Got 12, 8, 6
Got 48, 72, 96
Got 6912, 4608, 3456
Process ended
[[2, 3, 4], [12, 8, 6], [48, 72, 96], [6912, 4608, 3456]]

However, I am sure that this can be done with the usage of yield - mainly the values list creation part, which, as you see, is filled manually by me in the function.

The reason why I bother at all is just why the yield is used in the first place - here it doesn't matter, but what if my task required the 100000th value from this list - constructing it as a whole is not required, or even plainly stupid considering I don't want the previous 99999 values...

I tried using something like:

def compute_y(a, b, c):
    while True:
        yield b*c, a*c, b*a

for a, b, c in compute_y(2, 3, 4):
    if a > 9999:
        break

The problem with this is that the numbers in the for are the same all the time (2, 3 and 4), so it's never gonna reach other values and because of that it's an infinite loop.

tl;dr - can I use yield here at all to make the algorithm more efficient for bigger lists?


Solution

  • Yep, you’ll need to assign the new values for the next loop iteration:

    def compute_y(a, b, c):
        while True:
            yield a, b, c
            a, b, c = b*c, a*c, b*a