On Mon, Dec 09, 2019 at 10:19:43PM -0400, Juancarlo Añez wrote:
> And knowing that you must use *iter()* for 2-arg *next()* to (maybe) work
> right is idiosyncratic.
If you think that knowing to use `iter` before calling `next` is somehow
advanced or difficult knowledge, I think that you have an exaggerated
idea of the ineptitude of the average Python programmer.
Anyone who calls `next` directly on a list or other non-iterator will
get a TypeError:
TypeError: 'list' object is not an iterator
which makes it pretty obvious that the solution is to call `iter` first.
I know absolute beginners won't read error messages, but that's a skill
that people learn pretty quickly.
> It takes a "Python historian" to understand why it *may be correct* to use:
>
> the_first_item_if_ordered = next(iter(container), default='not found')
What do you mean by "may be correct"? Can you give an example of when it
isn't correct, assuming `container` is an iterable?
> While the semantics of *first()* (whichever the chosen implementation) are
> straightforward to explain:
>
>
> one_item_if_any = first(return_a_set(), default=-1)
I don't think it's more straightforward than the `next` version. There
are at least two gotchas, or possibly two sides of the same gotcha, one
minor and one (in my opinion) major.
The first is that, in a sense, the name `first` is misleading: it
doesn't return the *first* item from an iterator, since the first item
may be long gone; it returns the *next* item of an iterator.
If I have `letters = iter("abcde...z")` and have already advanced into
the middle of the iterator, a naive user might expect that
first(letters)
will return "a" rather than whatever the next letter happens to be.
But the more serious gotcha is that `first` behaves very differently
when called repeatedly on an iterator compared to other iterables.
> I agree with others in that the "*default*" argument should be explicit
> instead of implied. It's how *dict.get()*, and *dict.pop()*, etc., work.
When you say "explicit instead of implied", do you mean that there is no
default value for the default?
If so, that's not how dict.get works:
py> {}.get('some key') is None
True
--
Steven
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/QWJALBOXOEYRS2OUIAUKHDLNMAPQTABO/
Code of Conduct: http://python.org/psf/codeofconduct/