Search code examples
pythoniteratorgeneratoroperator-precedenceassign

Python unexpected StopIteration


This is my code

class A:
    pass

def f():
    yield A()

def g():
    it = f()
    next(it).a = next(it, None)

g()

that produces the StopIteration error, caused by next(it).a = next(it, None). Why?

The documentation says that next function does not raise the StopIteration if the default value is provided, and I expected it to get me the first item from the generator (the A instance) and set the a attribute to None.


Solution

  • Because f only yields a single value, you can only call next on it once.

    The right hand side of your expression (next(it, None)) is evaluated before the left hand side, and thus exhausts the generator.

    Calling next(it).a on the left hand side will then raise StopIteration.