我刚刚发明了一个愚蠢的小辅助函数:
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
...这对我来说很好,因为我知道 seq 很小,但感觉很奇怪。是否有一个我在这里忘记的习语阻止我不得不打破这个助手?
澄清
回想起来,这是一个很糟糕的问题,尽管我们得到了一些很好的答案!我一直在寻找:
- 一个明显且可读的内联习语或 stdlib 函数,在这种情况下可以接受急切的评估。
- 一个更明显和可读的辅助函数——因为它打破了一个完整的其他函数,所以只有最小的评估量似乎是可以接受的。
@Stephan202为辅助函数提出了一个非常酷的成语, @ Martin v. Löwis在谓词返回布尔值的假设下提出了一个更简单的内联成语。谢谢@大家的帮助!