On 12/13/2014 5:36 PM, Antoine Pitrou wrote:
On Sat, 13 Dec 2014 17:31:36 -0500 Terry Reedy
wrote: On 12/13/2014 7:45 AM, Oscar Benjamin wrote:
On 10 December 2014 at 18:35, Guido van Rossum
wrote: If you had both next() and take() to choose from then the only time next() would be preferable is when you want to leak StopIteration (a pattern that is now largely broken by PEP 479).
BTW did you know that next(iterator, default) returns default if the iterator is exhausted? IOW this will never raise StopIteration. It's similar to dict.get(key, default) or getattr(obj, attrname, default).
I more often find that I want an error than a default value and of
I once proposed, either here or on python-list, and propose again, that the signature of next be expanded so that the user could specify the ending exception. If possible, the stop object could either be an exception class, which would be called with a generic message, or an exception instance.
Then the awkward
try: item = next(it) except StopIteration: raise ValueError('iterable must not be empty') from None
I don't remember ever needing to write such code.
Others do, whenever the first item of an iterable needs special treatment. And others *have* forgotten to catch StopIteration when calling next(it). The code for reduce *is* written with such code.
from functools import reduce as r r(lambda a, b: a+b, []) Traceback (most recent call last): File "
", line 1, in <module> r(lambda a, b: a+b, []) TypeError: reduce() of empty sequence with no initial value
But the current equivalent code in the doc is buggy because it was not. def reduce(function, iterable, initializer=None): it = iter(iterable) if initializer is None: value = next(it) else: value = initializer for element in it: value = function(value, element) return value
reduce(lambda a, b: a+b, []) Traceback (most recent call last): File "C:\Programs\Python34\tem.py", line 11, in <module> reduce(lambda a, b: a+b, []) File "C:\Programs\Python34\tem.py", line 4, in reduce value = next(it) StopIteration
The equivalent code now would be try: value = next(it) except StopIteration: raise TypeError("reduce() of empty sequence with no initial value") from None http://bugs.python.org/issue23049? That a core developer would miss this illustrates to me why the addition is needed. With this proposal, the correct equivalent would be value = next(it. stop=TypeError( "reduce() of empty sequence with no initial value")) -- Terry Jan Reedy