Мне интересно, есть ли там причина, по которой нет first(iterable) в встроенных функциях Python, несколько похожа на any(iterable) и all(iterable) (она может быть заправлена в модуль stdlib где-то, но я не знаю, см. его в itertools). first выполнит оценку генератора короткого замыкания, чтобы избежать ненужных (и потенциально бесконечного числа) операций; то есть.
def identity(item):
return item
def first(iterable, predicate=identity):
for item in iterable:
if predicate(item):
return item
raise ValueError('No satisfactory value found')
Таким образом вы можете выразить такие вещи, как:
denominators = (2, 3, 4, 5)
lcd = first(i for i in itertools.count(1)
if all(i % denominators == 0 for denominator in denominators))
Ясно, что вы не можете сделать list(generator)[0] в этом случае, так как генератор не заканчивается.
Или если у вас есть куча регулярных выражений, которые нужно сопоставить (полезно, когда все они имеют один и тот же интерфейс groupdict):
match = first(regex.match(big_text) for regex in regexes)
Вы сохраняете много ненужной обработки, избегая list(generator)[0] и короткого замыкания в положительном совпадении.