It really ius frustrating how often we repeat entire conversations on this list :-(

But last time, one of the use cases was "get a random item from a dict", and there really is not a terribly easy (and efficient) way to do that now.

Anyway, I do see the benefit of adding first() to itertools -- there really is a key problem with:

next(iter(an_iterable))

for newbies -- you can get really really far in Python without ever having to call  either next() or iter(). Sure, if it's a recipe, people can use it without really understanding it, but  having an easy and obvious solution would be nice.

NOTE: I actually use this as a teaching moment in my intro to Python class: we have an assignment where there is a need to grab an arbitrary (not necessarily random) item from a dict (without removing it). most students come up with something like:

random.choice(list(the_dict.items()))

which works fine for any but the largest of dicts, but is not an optimum solution.

I don't think anyone has ever come up with next(iter(the_dict.items)) on their own.

So I have a little lesson where I run through the options, and use it as a chance to introduce the iterator protocol. So it's a good teaching moment, but not a great example of how Python usually has an easy and obvious way to do seemingly simple operations.

-CHB






On Thu, Oct 7, 2021 at 12:44 AM Stephen J. Turnbull <stephenjturnbull@gmail.com> wrote:
Finn Mason writes:

 > We don't need people writing `next(iter(iterable))` just to get the
 > first item.

We already don't need that.  `sequence[0]` and `next(iterator)` do the
trick.

You only need `next(iter(iterable))` if you need all three of

- an expression (`for first in iterable: break` gives the other two),
- efficient (although the difference with the `for` idiom should
  usually be irrelevant)
- polymorphic over sequences and iterators (both special notations are
  more efficient expressions).

and it makes it explicit that that's what you're after.

At least for beginners, putting this idiom in the Tutorial is probably
the best idea.  With the exception of wacko iterables that define
`__next__` but not `__iter__` (which `first` could take care of, but
do we really want to do that? I guess we should if we're going to
define `first`), not only is the idiom the efficient polymorphic
expression, but to understand why it works teachs a lot about
iterables vs. iterators vs. sequences.

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@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/5LQ5TIEDK3PGYB5CYD4GZ7ZMZE7YVWXY/
Code of Conduct: http://python.org/psf/codeofconduct/


--
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython