From 31b26f637aa118c70157a3e11f58f12620345989 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 2 Apr 2014 03:16:42 -0700 Subject: [PATCH] Issue #18652: Add an itertools recipe for first_true() --- Doc/library/itertools.rst | 13 +++++++++++++ Lib/test/test_itertools.py | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 5d3e50a86dd..f489535c536 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -784,6 +784,19 @@ which incur interpreter overhead. except exception: pass + 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) + def random_product(*args, repeat=1): "Random selection from itertools.product(*args, **kwds)" pools = [tuple(pool) for pool in args] * repeat diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 21f1bdeb82c..3a580ad9b2d 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1998,6 +1998,19 @@ Samuele ... # unique_justseen('ABBCcAD', str.lower) --> A B C A D ... return map(next, map(itemgetter(1), groupby(iterable, key))) +>>> 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) + This is not part of the examples but it tests to make sure the definitions perform as purported. @@ -2075,6 +2088,9 @@ True >>> list(unique_justseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'A', 'D'] +>>> first_true('ABC0DEF1', '9', str.isdigit) +'0' + """ __test__ = {'libreftest' : libreftest}