Я только что изобрел дурацкую вспомогательную функцию:
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.
Потому что самая читаемая/идиоматическая встроенная вещь, которую я мог придумать, была:
[predicate(item) for item in seq].count(True) == 1
... в моем случае это нормально, потому что я знаю, что последовательность небольшая, но это просто странно. Я забыл здесь идиому, из-за которой мне не нужно использовать этот помощник?
Уточнение
Оглядываясь назад, понимаю, что это был довольно дерьмовый вопрос, хотя мы получили несколько отличных ответов! Я искал либо:
- Очевидная и удобочитаемая встроенная идиома или функция stdlib, в этом случае приемлема активная оценка.
- Более очевидная и удобочитаемая вспомогательная функция — поскольку она вызывает совершенно другую функцию, приемлемым кажется только минимальное количество вычислений.
@Stephan202 придумал действительно крутую идиому для вспомогательной функции и @Martin v. Löwis придумал более простую встроенную идиому в предположении, что предикат возвращает логическое значение . @Спасибо всем за помощь!