Мне интересно, есть ли там причина, по которой нет 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]
и короткого замыкания в положительном совпадении.