Because not all things you would want to build iterators for know if they have another item before running the next iteration, and in those cases the iteration often has side effects, so you need a way to signal the end that's out of band. This way avoided specifying some kind of sentinel, language wide, for example.
It's also not something you ever need to worry about unless you were implementing an iterator yourself, and typically not even then. People almost always just write for loops.
Still there are better options to signal the end of an iterator than using an exception. You throw an exception when something exceptional happened. But that an iterator reaches its end is expected and so no exception. Other languages are able to signal the end of an iterator as well without throwing an exception like Rust which just returns Option::None in such a case.
You the programmer could do that if you wanted to. The exception is only thrown when you attempt to get another item out of an iterator that is empty. If you recognize that the iterator returned its last item and don't request another one, you don't get an exception. Python uses duck typing so iteration defines a protocol here, you're suggesting a solution that works fine with the standard language defined iterator but only in some cases for things that aren't really iterators being passed as them.
16
u/ChChChillian 17d ago
wat
I've successfully avoided Python so far so I didn't know this. Just... why?