The problem is that first() does not return the first item of the iterator, but the *next item still available*.
a = list('12345') b = iter('12345')
first(a) == first(a) # True first(b) == first(b) # False
This is an excellent point, and something I hadn't considered. Unless someone can think of a good workaround that doesn't make the implementation hideously complex, I retract my support for adding `first()` and `last()` to itertools.
On 10 Oct 2021, at 05:09, Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Oct 06, 2021 at 03:42:28PM +0100, Alex Waygood wrote:
Whether they are added to dict or itertools, there are still nine of them
No, the suggestion was to add two functions to itertools (first() and last(), which would work with any iterable, not just dicts), rather than adding nine methods to the dict interface. This was precisely why I was saying that I liked the itertools solution more.
Okay.
In another post, I've explained why I don't think that putting first() in itertools would actually be useful (TL;DR: newbies wouldn't know it was there, and to people experienced enough to know it was there, it's likely easier to just use next() directly).
When I started writing this post, I was going to argue that we should put first() and last() in itertools as recipes, for their pedagogical value:
def first(iterable): return next(iter(iterable))
def last(iterable): return next(reversed(iterable))
I had got so far as to open bugs.python.org to create a ticket.
But I've convinced myself that they aren't even worthwhile as recipes. The problem is that if we are being precise and accurate, and we should be, the names are simply *wrong* and the behaviour will be confusing to those we're supposedly trying to help.
The problem is that first() does not return the first item of the iterator, but the *next item still available*.
a = list('12345') b = iter('12345')
first(a) == first(a) # True first(b) == first(b) # False
If that behaviour makes sense to you, and is what you expected, then congratulations, you're probably a very sophisticated Pythonista who understands that iterators mutate after each item is retrieved, in which case you probably aren't going to get any benefit at all from a named first() function.
But if you are one of those newbies who (we're told) need a named function, then you will probably be totally gobsmacked that sometimes first() will return the first item, and always the first item, and sometimes it will return the first, second, third... items in sequence.
If we are to be precise and accurate, *sequences* have a first item, but iterators only have a next item.
-- Steve _______________________________________________ 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/F6TG5E... Code of Conduct: http://python.org/psf/codeofconduct/