Search code examples
pythongenerator

How to have nested generators continue their logic while parent generators needs to stop?


Lets say I have the following code

def top():
    counter = 0

    for ch in child_1():
        print(ch)
        counter += 1

        if counter > 2:
            break


def child_1():
    for ch in child_2():
        yield ch

    print("child_1 logic has finished")


def child_2():
    for ch in "123456789":
        yield ch

    print("child_2 logic has finished")


if __name__ == '__main__':
    top()

Is there a way to have top() method to exit in the middle of the iteration like I have the counter condition, but let the children to finish their logic? (get to the code after the yield statement)

I tried to use while loop and other python tricks but it all went unsuccessful, I don't think there's a way without modifying the nested generators to not be a generators but I'm trying my shot here :D


Solution

  • If you want the children to "finish" what they're doing (i.e. perform the rest of the iteration), keep a reference to the iterator, and exhaust it after you break:

    def top():
        counter = 0
    
        iter_1 = child_1()
        for ch in iter_1:
            print(ch)
            counter += 1
    
            if counter > 2:
                break
    
        for _ in iter_1:
            pass