Thanks to everyone for the comments, especially Tim Chase for the simple and elegant tuple unpacking solution, and Léo El Amri for the detailed comments on the variants. Below are some more variants which *don't *use tuple unpacking, on the theory that the coding patterns may be useful in other cases where unpacking doesn't apply.
For me, one of the interesting lessons from all these finger exercises is that *for* and unpacking hide a lot of messiness, both the initial *iter* call and the exception handling. I don't see any way to eliminate the *iter*, but there are ways to avoid the verbose exception handling. Using the second arg to *next*, we get what is arguably a more elegant solution: _uniq = [] def firstg(iterable): it = iter(iterable) val0 = next(it,_uniq) val1 = next(it,_uniq) if val0 is not _uniq and val1 is _uniq: return val0 else: raise ValueError("first1: arg not exactly 1 long") But I don't know if the *_uniq* technique is considered Pythonic. If *next* were instead defined to return a flag (rather than raising an exception), the code becomes cleaner and clearer, something like this: def firsth(iterable): it = iter(iterable) (val0, good0) = next2(it) (val1, good1) = next2(it) # val1 is dummy if good0 and not good1: return val0 else: raise ValueError("first1: arg not exactly 1 long") # returns (value, validp) # validp is False if no more values def next2(iterable): try: val = next(iterable) except StopIteration: return (None, False) return (val, True) (To be clear, I'm *not *suggesting that *next2* replace *next*!) Thoughts? -s -- https://mail.python.org/mailman/listinfo/python-list