There seems to be a growing list of issues with adding `itertools.first(x)` as
shorthand for `next(iter(x))`:
* If `x` is an iterator, it modifies the iterator, which is counterintuitive
from the name `first`.
* It'll still be difficult for new users to find/figure out.
In the end, I feel like the main case I want to use a `first` and `last`
functions on are `dict`s; other objects like `range`, `str`, `list`, `tuple`
all support `[0]` and `[-1]`.
So I wonder whether we should go back to this idea:
On Tue, 5 Oct 2021, Alex Waygood wrote:
[...] Another possibility I've been wondering about was
whether several methods should be added to the dict interface:
* dict.first_key = lambda self: next(iter(self))
* dict.first_val = lambda self: next(iter(self.values()))
* dict.first_item = lambda self: next(iter(self.items()))
* dict.last_key = lambda self: next(reversed(self))
* dict.last_val = lambda self: next(reversed(self.values()))
* dict.last_item = lambda self: next(reversed(self.items()))
But I think I like a lot more the idea of adding general ways of doing these
things to itertools.
At the least, I wonder whether a `dict.lastitem` method that's the
nondestructive analog of `dict.popitem` would be good to add. This would
solve the case of "I want an arbitrary item from this dict, I don't care which
one, but I don't want to modify the dict so I'd rather not use popitem" which
I've seen repeated a few times in this thread.
By contrast, I don't think `next(iter(my_dict))` is an intuitive way to solve
this problem, even for many experts; and I don't think it's as efficient as
`my_dict.lastitem()` would be, because the current `dict` code maintains a
pointer to the last item but not to the first item.
[I also admit that I've mostly forgotten the original situation where I wanted
this functionality. I believe it was an exhaustive search, where I wanted to
branch on an arbitrary item of a dict, and nondestructively build new versions
of that dict for recursive calls (instead of modifying before recursion and
unmodifying afterward).]
One more idea to throw around: Consider the following "anonymous unpacking"
syntax.
```
first, * = [1, 2, 3]
*, last = [1, 2, 3]
```
For someone used to unpacking syntax, this seems like a natural extension to
what we have now, and is far more flexible than just extracting the first
element. The distinction from the existing methods (with e.g. `*_`) is that
it wouldn't waste time extracting elements you don't want. And it could work
well with things like `dict` (and `dict_items` etc.).
Erik
--
Erik Demaine | edema...@mit.edu | http://erikdemaine.org/
_______________________________________________
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/IQ2EJM5BTDEO4URUHN3XGR6XSXX22HFR/
Code of Conduct: http://python.org/psf/codeofconduct/