first_true
jest itertools
przepis znaleźć w Python 3 docs:
def first_true(iterable, default=False, pred=None):
"""Returns the first true value in the iterable.
If no true value is found, returns *default*
If *pred* is not None, returns the first item
for which pred(item) is true.
"""
# first_true([a,b,c], x) --> a or b or c or x
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
return next(filter(pred, iterable), default)
One mogą zdecydować się na wprowadzenie tego ostatniego przepisu lub importować more_itertools
, bibliotekę, że statki z itertools
receptur i nie tylko:
> pip install more_itertools
Użyj:
import more_itertools as mit
a = [None, None, None, 1, 2, 3, 4, 5]
mit.first_true(a, pred=lambda x: x is not None)
# 1
a = [None, None, None]
mit.first_true(a, default="All are None", pred=lambda x: x is not None)
# 'All are None'
Dlaczego używać predykatu?
"Pierwszy element inny niż None
" to nie to samo co element "pierwszy True
", np. [None, None, 0]
gdzie 0
jest pierwszym non-None
, ale nie jest pierwszym elementem o numerze True
. Predykat pozwala na użycie first_true
, zapewniając, że każdy pierwszy widoczny, nie-żaden, element falsey w iteracji jest nadal zwracany (na przykład 0
, False
) zamiast domyślnego.
a = [None, None, None, False]
mit.first_true(a, default="All are None", pred=lambda x: x is not None)
# 'False'
Dodałbym polecenie 'try:' z wyjątkiem StopIteration: 'do obsługi list zawierających tylko pozycje Brak. Ale to wspaniała odpowiedź. – Germano
@Germano zaktualizował odpowiedź, sprawdź. Przy okazji, odpowiedź Jona powinna zostać zaakceptowana - jako pierwszy zaproponował rozwiązanie dla list "tylko". – alecxe
w rzeczywistości myślę, że odpowiedź Jona jest niepoprawna: zwraca tylko wartość "Prawda" lub "Fałsz", a nie pierwsza pozycja "Brak" na liście. – Germano