I think a solution nobody has proposed in this thread is relaxing the next builtin, so it calls iter() on the argument when it doesn't implement the iterator protocol. That would make next([1, 2]) == 1, and also make next([], "missing") == "missing". After that all that is needed is educating the users a bit about the 2-argument form of next (which after this thread, sounds like a good idea by itself anyway). I don't think the performance impact should be big (it would add a check and a method call but only on a path that currently raises a TypeError, which shouldn't be typically in a hot path). Compatibility-wise, it potentially turns TypeError raising code into non-raising code, which might make a difference if someone is catching this and doing something special with it, but IMHO I don't think that's something that should happen a lot (and is the kind of backward incompatible changes that are tolerated between releases. Do you see any drawbacks I missed? Do you think this fails to cover the original problems in any way? On Wed, 11 Dec 2019 at 01:22, Tim Peters <tim.peters@gmail.com> wrote:
[Tim]
For me, most of the time, it's to have an obvious, uniform way to spell "non-destructively pick an object from a container (set, dict, list, deque, heap, tuple, custom tree class, ...)". I don't even have iterators in mind then, except as an implementation detail.
[Steven]
You can't *non-destructively* pick the first (or next, or any) element of an iterator.
Obviously. That's why I wrote "container", and then gave 7 concrete examples in case that distinction was too subtle ;-)
But do note my "most of the time" too. There are also uses for iterators, but for _me_ those are not most common. For others they may be.
... It sounds to me that what you actually want is an analogue to Mapping.get that applies to all containers and sequences and leaves iterators completely out of it.
No, I want `first()`. It solves more than one problem. For iterators I nearly always use plain `next(iterator)`, but there are (for _me_, rare) cases where I'd like to do, e.g., `first(iterator, sentinel)` instead.
I'm not at all bothered that for some arguments `first()` mutates state and for others it doesn't, no more than I'm bothered that `for x in iterable:` may or may not "consume" the iterable.
... I could completely get behind this idea! The only tricky part is the "index" isn't well-defined for mappings and sets, or tree-like containers.
While the meaning of `first()` is clear for any iterable argument. _______________________________________________ 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/PRMVKU... Code of Conduct: http://python.org/psf/codeofconduct/