On Sun, Dec 8, 2019 at 9:27 PM Andrew Barnert <abarnert@yahoo.com> wrote:
On Dec 8, 2019, at 20:59, Guido van Rossum <guido@python.org> wrote:
>
> But even if you know about 2-arg next(), the next(iter(it), default) version is not quite trivial to come up with -- you have to remember to put the iter() call in -- but IMO the main problem is that not enough people know about 2-arg next(), and that makes it pass the second bar.

Are people who never find 2-arg next going to find itertools.first?

Nobody is going to write a blog post about 2-arg next() (there just isn't enough for more than a sentence or two) but people write tutorials about itertools all the time, since it's such a rich module. So I think it's likely that first() will get some exposure that way.
 
I think most people who use itertools regularly enough to look there are people who already know 2-arg next (and also, mostly people who are “thinking functionally”, for that matter). Other people will discover it if someone points them there on -list or on StackOverflow or as student help or whatever, but they can already discover 2-arg next the same ways. In fact, what they’re probably going to find on StackOverflow is an answer all about 2-arg next, with a little edited-in footnote or comment saying “if you’re using the upcoming 3.9, you can use first instead of next and leave out the call to iter”.

If the only argument against adding a new feature is that existing documentation doesn't yet describe it, I'm not too concerned. :-)

I do have to admit that I'm probably biased because I didn't recall 2-arg next() myself until it was mentioned in this thread. But I doubt that I'm alone -- I've seen plenty of code written by people (other than me :-) who clearly didn't know about it either. I can't show examples, since what I recall was in a large proprietary code base to which I no longer have access. I did find this, in test_itertools.py no less:

>>> def pairwise(iterable):
...     "s -> (s0,s1), (s1,s2), (s2, s3), ..."
...     a, b = tee(iterable)
...     try:
...         next(b)
...     except StopIteration:
...         pass
...     return zip(a, b)

Methinks that could have been three lines shorter using next(b, None).

--
--Guido van Rossum (python.org/~guido)