On Dec 9, 2019, at 18:23, Juancarlo Añez <apal...@gmail.com> wrote:
> 
> 
>> So while 1-arg next() and the try/except StopIteration pattern are essential 
>> and well-known, 2-arg next() is relatively esoteric and consequently (I 
>> think) not nearly as well-known.
> 
> And knowing that you must use iter() for 2-arg next() to (maybe) work right 
> is idiosyncratic.
> 
> It takes a "Python historian" to understand why it may be correct to use:
> 
> the_first_item_if_ordered = next(iter(container), default='not found')

Why “may be correct”? It’s always correct. You can always call iter on any 
Iterable, you can always call next on the result with a default, so this always 
works.

And you don’t need to be a Python historian to know why it works; it follows 
directly from the documentation of the two functions and the meaning of 
Iterable. (You may need to be a Python historian to understand why people often 
don’t remember this and therefore don’t use it, but that seems like the kind of 
thing you’d expect to go to a historian for.)

> While the semantics of first() (whichever the chosen implementation) are 
> straightforward to explain:
>    
> one_item_if_any = first(return_a_set(), default=-1)
> 
> or:
> the_first_item = first(sorted(container))

But they both work exactly as well with next:

    one_item_if_any = next(iter(return_a_set()), default=-1)

That’s exactly what first means, and the doc string for the more_itertools 
version even directly tells you that it’s just a slightly shorter way to write 
the same thing.

If the argument for first is that it can do things you can’t do otherwise, or 
that there’s some subtle and complicated case in which next may not work that 
only historians can understand, the argument is just wrong.

The real argument for first is that it’s (hopefully) more discoverable than 
2-arg next. (That, and Tim’s argument that we should lower the bar for 
inclusion in itertools.)

> I agree with others in that the "default" argument should be explicit instead 
> of implied. It's how dict.get(), and dict.pop(), etc., work. The exceptions 
> raised when nothing can be returned from first() and there is no default= 
> should be the same.

KeyError? Why?

I think the ValueError suggested by many people in this thread (and used in 
multiple places in more_itertools) makes more sense. Trying to get the first 
value out of an empty Iterable is a lot like trying to use tuple unpacking on 
an empty Iterable; it’s not much like trying to look up a key in an empty dict.

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/H7ZHHWEOSSRHLVY5542RWXDSIHKZURTJ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to