I had always thought that a an exhausted iterator raises StopIteration
, and a loop catches that. This seems to align with what's said in https://bugs.python.org/issue31156. Now, running any of
a=[1,3]
itr = iter(a)
while True:
next(itr)
next(itr)
next(itr)
a=[1,3]
itr = iter(a)
for itr1 in itr:
next(itr)
next(itr)
next(itr)
crashes. This seems not to align with what's said in the above link:
A StopIteration exception raised in the body of a while loop will terminate (and is caught by) the while-loop, thus leading to graceful termination.
Has the behaviour changed?
CodePudding user response:
A for
loop like
for x in y:
<body>
is roughly equivalent to
itr = iter(y)
while True:
try:
x = next(itr)
except StopIteration:
break
<body>
(I say "roughly", because no name like itr
is exposed to the body of the loop, I'm not handling the else
clause of a for
loop, etc.)
Notice that StopIteration
is only caught when raised by the implicit call to next
used to set the value of x
, not if raised by something in the body of the loop.
Also note the last comment in the (now closed) issue from the reporter:
Sorry, that was my misinterpretation of what happened. I had been stumbling over an old program I had written, but apparently it works because the while-loop is inside a generator function, and the StopIteration is simply passed on.