
[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.