I just invented a stupid little helper function:
def has_one(seq, predicate=bool):
"""Return whether there is exactly one item in `seq` that matches
`predicate`, with a minimum of evaluation (short-circuit).
"""
iterator = (item for item in seq if predicate(item))
try:
iterator.next()
except StopIteration: # No items match predicate.
return False
try:
iterator.next()
except StopIteration: # Exactly one item matches predicate.
return True
return False # More than one item matches the predicate.
Because the most readable/idiomatic inline thing I could come up with was:
[predicate(item) for item in seq].count(True) == 1
... which is fine in my case because I know seq is small, but it just feels weird. Is there an idiom I’m forgetting here that prevents me from having to break out this helper?
Clarification
Looking back on it, this was kind of a crappily posed question, though we got some excellent answers! I was looking for either:
- An obvious and readable inline idiom or stdlib function, eager evaluation being acceptable in this case.
- A more obvious and readable helper function -- since it's breaking out a whole other function, only the minimum amount of evaluation seems acceptable.
@Stephan202 came up with a really cool idiom for the helper function and @Martin v. Löwis came up with a more simple inline idiom under the assumption that the predicate returns a bool. Thanks @ everybody for your help!