"Christophe" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Is there a good reason why when you try to take an element from an > already exausted iterator, it throws StopIteration instead of some other > exception ?
Yes. . . To distinguish the control message "I am done yielding values, as per the code specification (so don't bother calling me again)." from error messages that say "Something is wrong, I cannot yield values and give up." In other words, to distinguish expected correct behavior from unexpected incorrect behavior. This is essential for the normal and correct use of iterators. > I've lost quite some times already because I was using a lot > of iterators and I forgot that that specific function parameter was one. I think you mean 'specific function argument' for a parameter which could be any iterable. > Exemple : Example > >>> def f(i): > ... print list(i) > ... print list(i) > ... > >>> f(iter(range(2))) > [0, 1] > [] As per specification. I am guessing that you want the first list() call to terminate normally and return a list, which requires exhausted i to raise StopIteration, while you want the second list() to not terminate but raise an exception, which requires exhausted i to raise something other than StopIteration. Tough. One solution is call list(i) exactly once: def f(i): li = list(i) print li print li Another is to document f as requiring that i be a non-iterator reiterable iterable and only pass correct arguments. A third is to add a line like if iter(i) is i: raise TypeError("input appears to be iterator") This is not quite exact since it will improperly exclude self-iterator reiterables (which, I believe, no builtin is) and improperly pass non-reiterable non-iterator iterables (at least some file objects). But it might work for all your cases. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list