
[Tim]
Every suggestion here so far has satisfied that, if S is a non-empty set,
assert next(iter(S)) is first(S)
succeeds. That is, `first()` is _defined_ by reference to iteration order. It's "the first" in that order (hence the name).
[Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp>]
The problem I'm concerned with is that sometimes users' definitions of words differ from a computer language's definitions of words. That's why I used the word "natural", which doesn't really have much to do with the way a computer language defines things, but frequently features in human thought.
Whether that potential difference matters here is an empirical question.
Theoretically, I can say "Explicit is better than implicit." I.e., the call to 'iter' tells us exactly what order is being used.
But hasn't it already been settled by experience? There is nothing unique about `first(set)` implicitly appealing to iteration order. A set passed as the iterable to _any_ itertools function does exactly the same:
import itertools list(itertools.zip_longest(set("abcde"), range(5))) # can vary from run to run [('a', 0), ('e', 1), ('c', 2), ('d', 3), ('b', 4)] list(itertools.compress(set("abcde"), [1]*5)) # but is consistent within a run ['a', 'e', 'c', 'd', 'b'] list(itertools.takewhile(lambda x: True, set("abcde"))) ['a', 'e', 'c', 'd', 'b']
So do, e.g., some builtins:
list(map(ord, set("abcde"))) [97, 101, 99, 100, 98] [ord(ch) for ch in set("abcde")] [97, 101, 99, 100, 98]
That's *my* opinion in this case, and I don't hold *you* to it just because I'm quoting you. (I am amused, though.)
I just don't see the potential for "new" bafflement if itertools.first works exactly the same way as itertools.anything_else _has_ worked, in this respect, all along. Give users some credit. Programming is baffling, period, at first. But to those who persist, nothing becomes truly unbearable ;-)